Beispiel #1
0
    def test_do_not_go_to_next_question_for_date_answer(self):

        goto_rule = {
            "id":
            "next-question",
            "when": [{
                "id": "date-answer",
                "condition": "equals",
                "date_comparison": {
                    "value": "2018-01"
                },
            }],
        }

        answer_store = AnswerStore({})
        answer_store.add_or_update(
            Answer(answer_id="date-answer", value="2018-02-01"))

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

        self.assertFalse(
            evaluate_goto(
                goto_rule=goto_rule,
                schema=get_schema_mock(),
                metadata={},
                answer_store=answer_store,
                list_store=ListStore(),
                current_location=current_location,
            ))
def relationship_answer_store():
    answer_store = AnswerStore()

    answer_store.add_or_update(
        Answer(
            answer_id="relationship-answer",
            value=[
                {
                    "list_item_id": "abc123",
                    "to_list_item_id": "xyz987",
                    "relationship": "Husband or Wife",
                },
                {
                    "list_item_id": "abc123",
                    "to_list_item_id": "123abc",
                    "relationship": "Son or Daughter",
                },
                {
                    "list_item_id": "xyz987",
                    "to_list_item_id": "123abc",
                    "relationship": "Son or Daughter",
                },
            ],
        )
    )

    return answer_store
def test_minimum_and_maximum_offset_dates(app, value_source_resolver, rule_evaluator):
    value_source_resolver.metadata = {"date": "2018-02-20"}
    answer_store = AnswerStore()

    test_answer_id = Answer(answer_id="date", value="2018-03-20")
    answer_store.add_or_update(test_answer_id)
    value_source_resolver.answer_store = answer_store
    answer = {
        "id": "date_answer",
        "type": "Date",
        "minimum": {
            "value": {"identifier": "date", "source": "metadata"},
            "offset_by": {"days": -10},
        },
        "maximum": {
            "value": {"identifier": "date", "source": "answers"},
            "offset_by": {"years": 1},
        },
    }

    handler = DateHandler(answer, value_source_resolver, rule_evaluator, error_messages)
    minimum_date = handler.get_date_value("minimum")
    maximum_date = handler.get_date_value("maximum")

    assert minimum_date == parse_datetime("2018-02-10")
    assert maximum_date == parse_datetime("2019-03-20")
Beispiel #4
0
def test_get_referenced_offset_value_with_list_item_id(app, schema_mock):
    list_item_id = "abcde"
    answer_store = AnswerStore()

    test_answer_id = Answer(answer_id="date",
                            value="2018-03-20",
                            list_item_id=list_item_id)

    location = Location(section_id="test", list_item_id=list_item_id)

    answer_store.add_or_update(test_answer_id)

    answer = {
        "maximum": {
            "value": {
                "identifier": "date",
                "source": "answers"
            },
            "offset_by": {
                "months": 1
            },
        }
    }

    handler = DateHandler(answer, answer_store=answer_store, location=location)
    maximum_date = handler.get_date_value("maximum")

    assert maximum_date == convert_to_datetime("2018-04-20")
Beispiel #5
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.get_list_item_id_for_answer_id = Mock(return_value=list_item_id)

        self.assertTrue(
            evaluate_when_rules(
                when_rules=when["when"],
                schema=schema,
                metadata={},
                answer_store=answer_store,
                list_store=ListStore(),
                current_location=current_location,
            ))
def test_get_referenced_offset_value_with_list_item_id(
    app, value_source_resolver, rule_evaluator
):
    list_item_id = "abcde"

    test_answer_id = Answer(
        answer_id="date", value="2018-03-20", list_item_id=list_item_id
    )

    location = Location(section_id="test", list_item_id=list_item_id)

    answer_store = AnswerStore()

    answer_store.add_or_update(test_answer_id)
    value_source_resolver.answer_store = answer_store
    value_source_resolver.location = location
    value_source_resolver.list_item_id = list_item_id
    answer = {
        "maximum": {
            "value": {"identifier": "date", "source": "answers"},
            "offset_by": {"months": 1},
        }
    }

    handler = DateHandler(answer, value_source_resolver, rule_evaluator, error_messages)
    maximum_date = handler.get_date_value("maximum")

    assert maximum_date == parse_datetime("2018-04-20")
    def test_get_routing_path_when_first_block_in_group_skipped(self):
        # Given
        schema = load_schema_from_name("test_skip_condition_group")
        answer_store = AnswerStore()
        answer_store.add_or_update(
            Answer(answer_id="do-you-want-to-skip-answer", value="Yes"))

        # When
        path_finder = PathFinder(schema, answer_store, self.list_store,
                                 self.progress_store, self.metadata)

        # Then
        expected_route = [
            {
                "block_id": "do-you-want-to-skip-block",
                "group_id": "do-you-want-to-skip-group",
            },
            {
                "block_id": "summary",
                "group_id": "should-skip-group"
            },
        ]

        section_id = schema.get_section_id_for_block_id("summary")
        pytest.xfail(
            reason=
            "Known bug when skipping last group due to summary bundled into it"
        )

        self.assertEqual(path_finder.routing_path(section_id=section_id),
                         expected_route)
    def test_meta_comparison_missing(self):
        # Given
        goto_rule = {
            "id":
            "next-question",
            "when": [{
                "condition": "equals",
                "meta": "variant_flags.does_not_exist.does_not_exist",
                "value": True,
            }],
        }
        answer_store = AnswerStore()
        answer_store.add_or_update(Answer(answer_id="my_answer", value="Yes"))
        metadata = {"varient_flags": {"sexual_identity": True}}

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

        self.assertFalse(
            evaluate_goto(
                goto_rule=goto_rule,
                schema=get_schema(),
                metadata=metadata,
                answer_store=answer_store,
                list_store=ListStore(),
                current_location=current_location,
            ))
    def test_should_not_go_to_next_question_when_second_condition_fails(self):
        # Given
        goto_rule = {
            "id":
            "next-question",
            "when": [
                {
                    "id": "my_answer",
                    "condition": "equals",
                    "value": "Yes"
                },
                {
                    "condition": "equals",
                    "meta": "sexual_identity",
                    "value": False
                },
            ],
        }
        answer_store = AnswerStore()
        answer_store.add_or_update(Answer(answer_id="my_answer", value="Yes"))
        metadata = {"sexual_identity": True}

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

        self.assertFalse(
            evaluate_goto(
                goto_rule=goto_rule,
                schema=get_schema(),
                metadata=metadata,
                answer_store=answer_store,
                list_store=ListStore(),
                current_location=current_location,
            ))
    def test_do_not_go_to_next_question_for_multiple_answers(self):
        # Given
        goto_rule = {
            "id":
            "next-question",
            "when": [
                {
                    "id": "my_answer",
                    "condition": "equals",
                    "value": "Yes"
                },
                {
                    "id": "my_other_answer",
                    "condition": "equals",
                    "value": "2"
                },
            ],
        }
        answer_store = AnswerStore()
        answer_store.add_or_update(Answer(answer_id="my_answer", value="No"))

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

        self.assertFalse(
            evaluate_goto(
                goto_rule=goto_rule,
                schema=get_schema(),
                metadata={},
                answer_store=answer_store,
                list_store=ListStore(),
                current_location=current_location,
            ))
    def test_evaluate_goto_returns_true_when_answer_value_not_equals_any_match_values(
        self, ):

        goto = {
            "id":
            "next-question",
            "when": [{
                "id": "my_answers",
                "condition": "not equals any",
                "values": ["answer1", "answer2"],
            }],
        }
        answer_store = AnswerStore()
        answer_store.add_or_update(
            Answer(answer_id="my_answers", value="answer3"))

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

        self.assertTrue(
            evaluate_goto(
                goto_rule=goto,
                schema=get_schema(),
                metadata={},
                answer_store=answer_store,
                list_store=ListStore(),
                current_location=current_location,
            ))
    def test_sum_calculated_field(self):
        store = AnswerStore()

        answer_total = Answer(answer_id="total-answer", value=10)

        store.add_or_update(answer_total)

        with self.app_request_context():
            schema = load_schema_from_name("test_sum_equal_validation_against_total")

            question_schema = schema.get_block("breakdown-block").get("question")

            form_data = MultiDict(
                {
                    "breakdown-1": "",
                    "breakdown-2": "5",
                    "breakdown-3": "4",
                    "breakdown-4": "1",
                }
            )

            expected_form_data = {
                "csrf_token": "",
                "breakdown-1": None,
                "breakdown-2": Decimal("5"),
                "breakdown-3": Decimal("4"),
                "breakdown-4": Decimal("1"),
            }
            form = generate_form(
                schema, question_schema, store, metadata=None, form_data=form_data
            )

            form.validate()
            self.assertEqual(form.data, expected_form_data)
    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.is_repeating_answer = Mock(return_value=False)

        self.assertFalse(
            evaluate_when_rules(
                when_rules=when["when"],
                schema=schema,
                metadata={},
                answer_store=answer_store,
                list_store=ListStore(),
                current_location=current_location,
            ))
    def test_generate_form_with_title_and_no_answer_label(self):
        """
        Checks that the form is still generated when there is no answer label but there is a question title
        """
        store = AnswerStore()

        conditional_answer = Answer(answer_id="behalf-of-answer", value="chad")

        store.add_or_update(conditional_answer)

        with self.app_request_context():
            schema = load_schema_from_name("test_title")

            question_schema = schema.get_block("single-title-block").get("question")

            form_data = MultiDict({"feeling-answer": "good"})

            expected_form_data = {"csrf_token": "", "feeling-answer": "good"}

            with patch(
                "app.questionnaire.path_finder.evaluate_goto", return_value=False
            ):
                form = generate_form(
                    schema, question_schema, store, metadata={}, form_data=form_data
                )

            form.validate()
            assert form.data == expected_form_data
Beispiel #15
0
def test_choose_content_to_display(content_variant_schema):
    schema = QuestionnaireSchema(content_variant_schema)
    answer_store = AnswerStore({})
    answer_store.add_or_update(Answer(answer_id="age-answer", value="18"))
    metadata = {}

    block = schema.get_block("block1")
    section_id = schema.get_section_id_for_block_id(block["id"])

    content_to_display = choose_content_to_display(
        schema.get_block("block1"),
        schema,
        metadata,
        answer_store,
        ListStore({}),
        Location(section_id=section_id, block_id=block["id"]),
    )

    assert content_to_display[0]["title"] == "You are over 16"

    answer_store = AnswerStore({})

    content_to_display = choose_content_to_display(
        schema.get_block("block1"),
        schema,
        metadata,
        answer_store,
        ListStore({}),
        Location(section_id=section_id, block_id=block["id"]),
    )

    assert content_to_display[0]["title"] == "You are ageless"
Beispiel #16
0
    def test_routing_path_empty_routing_rules(self):
        schema = load_schema_from_name("test_checkbox")
        section_id = schema.get_section_id_for_block_id("mandatory-checkbox")
        expected_path = RoutingPath(
            [
                "mandatory-checkbox", "non-mandatory-checkbox",
                "single-checkbox"
            ],
            section_id="default-section",
        )

        answer_1 = Answer(answer_id="mandatory-checkbox-answer",
                          value="Cheese")
        answer_2 = Answer(answer_id="non-mandatory-checkbox-answer",
                          value="deep pan")
        answer_3 = Answer(answer_id="single-checkbox-answer", value="Estimate")

        answer_store = AnswerStore()
        answer_store.add_or_update(answer_1)
        answer_store.add_or_update(answer_2)
        answer_store.add_or_update(answer_3)

        progress_store = ProgressStore([{
            "section_id": "default-section",
            "list_item_id": None,
            "status": CompletionStatus.COMPLETED,
            "block_ids": ["mandatory-checkbox"],
        }])

        path_finder = PathFinder(schema, answer_store, self.list_store,
                                 progress_store, self.metadata)
        routing_path = path_finder.routing_path(section_id=section_id)

        self.assertEqual(routing_path, expected_path)
    def test_routing_path_should_not_skip_group(self):
        # Given
        schema = load_schema_from_name("test_skip_condition_group")

        section_id = schema.get_section_id_for_block_id("do-you-want-to-skip")
        answer_store = AnswerStore()
        answer_store.add_or_update(
            Answer(answer_id="do-you-want-to-skip-answer", value="No"))
        progress_store = ProgressStore([{
            "section_id": "default-section",
            "list_item_id": None,
            "status": CompletionStatus.COMPLETED,
            "block_ids": ["do-you-want-to-skip"],
        }])

        # When
        path_finder = PathFinder(schema, answer_store, self.list_store,
                                 progress_store, self.metadata)
        routing_path = path_finder.routing_path(section_id=section_id)

        # Then
        expected_routing_path = RoutingPath(
            [
                "do-you-want-to-skip", "should-skip", "last-group-block",
                "summary"
            ],
            section_id="default-section",
        )

        with patch("app.questionnaire.path_finder.evaluate_skip_conditions",
                   return_value=False):
            self.assertEqual(routing_path, expected_routing_path)
Beispiel #18
0
    def test_get_routing_path_when_first_block_in_group_skipped(self):
        # Given
        schema = load_schema_from_name("test_skip_condition_group")
        answer_store = AnswerStore()
        answer_store.add_or_update(
            Answer(answer_id="do-you-want-to-skip-answer", value="Yes"))

        # When
        path_finder = PathFinder(
            schema,
            answer_store,
            self.list_store,
            self.progress_store,
            self.metadata,
            self.response_metadata,
        )

        # Then
        expected_route = RoutingPath(
            section_id="default-section",
            block_ids=["do-you-want-to-skip"],
        )

        self.assertEqual(
            expected_route,
            path_finder.routing_path(section_id="default-section"),
        )
Beispiel #19
0
    def test_routing_path_with_conditional_path(self):
        schema = load_schema_from_name("test_new_routing_number_equals")
        section_id = schema.get_section_id_for_block_id("number-question")
        expected_path = RoutingPath(
            ["number-question", "correct-answer"],
            section_id="default-section",
        )

        answer = Answer(answer_id="answer", value=123)
        answer_store = AnswerStore()
        answer_store.add_or_update(answer)
        progress_store = ProgressStore([{
            "section_id": "default-section",
            "list_item_id": None,
            "status": CompletionStatus.COMPLETED,
            "block_ids": ["number-question"],
        }])
        path_finder = PathFinder(
            schema,
            answer_store,
            self.list_store,
            progress_store,
            self.metadata,
            self.response_metadata,
        )

        routing_path = path_finder.routing_path(section_id=section_id)

        self.assertEqual(routing_path, expected_path)
Beispiel #20
0
    def test_new_routing_basic_and_conditional_path(self):
        # Given
        schema = load_schema_from_name("test_new_routing_number_equals")
        section_id = schema.get_section_id_for_block_id("number-question")
        expected_path = RoutingPath(
            ["number-question", "correct-answer"],
            section_id="default-section",
        )

        answer_1 = Answer(answer_id="answer", value=123)

        answer_store = AnswerStore()
        answer_store.add_or_update(answer_1)

        # When
        path_finder = PathFinder(
            schema,
            answer_store,
            self.list_store,
            self.progress_store,
            self.metadata,
            self.response_metadata,
        )
        routing_path = path_finder.routing_path(section_id=section_id)

        # Then
        self.assertEqual(routing_path, expected_path)
Beispiel #21
0
    def test_new_routing_path_should_skip_group(self):
        # Given
        schema = load_schema_from_name("test_new_skip_condition_group")

        section_id = schema.get_section_id_for_block_id("do-you-want-to-skip")
        answer_store = AnswerStore()
        answer_store.add_or_update(
            Answer(answer_id="do-you-want-to-skip-answer", value="Yes"))
        progress_store = ProgressStore([{
            "section_id": "default-section",
            "list_item_id": None,
            "status": CompletionStatus.COMPLETED,
            "block_ids": ["do-you-want-to-skip"],
        }])

        # When
        path_finder = PathFinder(
            schema,
            answer_store,
            self.list_store,
            progress_store,
            self.metadata,
            self.response_metadata,
        )
        routing_path = path_finder.routing_path(section_id=section_id)

        # Then
        expected_routing_path = RoutingPath(
            ["do-you-want-to-skip"],
            section_id="default-section",
        )

        self.assertEqual(routing_path, expected_routing_path)
Beispiel #22
0
def test_transform_variants_with_question_variants(question_variant_schema):
    schema = QuestionnaireSchema(question_variant_schema)
    answer_store = AnswerStore({})
    answer_store.add_or_update(Answer(answer_id="when-answer", value="no"))
    metadata = {}

    block = schema.get_block("block1")
    section_id = schema.get_section_id_for_block_id(block["id"])

    transformed_block = transform_variants(
        block,
        schema,
        metadata,
        answer_store,
        ListStore({}),
        Location(section_id=section_id, block_id=block["id"]),
    )

    compare_transformed_block(block, transformed_block, "Question 1, No")

    answer_store.add_or_update(Answer(answer_id="when-answer", value="yes"))

    transformed_block = transform_variants(
        block,
        schema,
        metadata,
        answer_store,
        ListStore({}),
        Location(section_id=section_id, block_id=block["id"]),
    )

    compare_transformed_block(block, transformed_block, "Question 1, Yes")
Beispiel #23
0
def test_choose_question_to_display(question_variant_schema):
    schema = QuestionnaireSchema(question_variant_schema)
    answer_store = AnswerStore({})
    answer_store.add_or_update(Answer(answer_id="when-answer", value="yes"))
    metadata = {}

    block = schema.get_block("block1")
    section_id = schema.get_section_id_for_block_id(block["id"])

    question_to_display = choose_question_to_display(
        schema.get_block("block1"),
        schema,
        metadata,
        answer_store,
        ListStore({}),
        Location(section_id=section_id, block_id=block["id"]),
    )

    assert question_to_display["title"] == "Question 1, Yes"

    answer_store = AnswerStore({})

    question_to_display = choose_question_to_display(
        schema.get_block("block1"),
        schema,
        metadata,
        answer_store,
        ListStore({}),
        Location(section_id=section_id, block_id=block["id"]),
    )

    assert question_to_display["title"] == "Question 1, No"
    def test_bespoke_message_for_sum_validation(self):
        store = AnswerStore()

        answer_total = Answer(answer_id="total-answer", value=10)

        store.add_or_update(answer_total)

        with self.app_request_context():
            schema = load_schema_from_name("test_sum_equal_validation_against_total")

            question_schema = QuestionnaireSchema.get_mutable_deepcopy(
                schema.get_block("breakdown-block").get("question")
            )

            question_schema["validation"] = {
                "messages": {"TOTAL_SUM_NOT_EQUALS": "Test Message"}
            }

            form_data = MultiDict({"breakdown-1": "3", "breakdown-2": "5"})

            form = generate_form(
                schema, question_schema, store, metadata=None, form_data=form_data
            )

            with patch(
                "app.questionnaire.questionnaire_schema.QuestionnaireSchema.get_all_questions_for_block",
                return_value=[question_schema],
            ):
                form.validate()
                self.assertIn(
                    form.question_errors["breakdown-question"], "Test Message"
                )
    def test_invalid_date_range_and_single_date_periods(self):
        with self.app_request_context():
            store = AnswerStore()
            test_answer_id = Answer(answer_id="date", value="2017-03-20")
            store.add_or_update(test_answer_id)

            schema = load_schema_from_name("test_date_validation_range")

            question_schema = {
                "id": "date-range-question",
                "type": "DateRange",
                "answers": [
                    {
                        "id": "date-range-from",
                        "label": "Period from",
                        "mandatory": True,
                        "type": "Date",
                        "minimum": {"value": "2018-01-10", "offset_by": {"days": -5}},
                    },
                    {
                        "id": "date-range-to",
                        "label": "Period to",
                        "mandatory": True,
                        "type": "Date",
                        "maximum": {
                            "value": {"identifier": "date", "source": "answers"},
                            "offset_by": {"days": 5},
                        },
                    },
                ],
            }

            form_data = MultiDict(
                {
                    "date-range-from-day": "6",
                    "date-range-from-month": "1",
                    "date-range-from-year": "2018",
                    "date-range-to-day": "15",
                    "date-range-to-month": "1",
                    "date-range-to-year": "2018",
                }
            )

            metadata = {"schema_name": "test_date_validation_range"}

            form = generate_form(
                schema, question_schema, store, metadata=metadata, form_data=form_data
            )

            with self.assertRaises(Exception) as ite:
                with patch(
                    "app.questionnaire.questionnaire_schema.QuestionnaireSchema.get_all_questions_for_block",
                    return_value=[question_schema],
                ):
                    form.validate()
                    self.assertEqual(
                        "The schema has invalid date answer limits for date-range-question",
                        str(ite.exception),
                    )
    def test_remove_answer_and_block_if_routing_backwards(self):
        schema = load_schema_from_name("test_confirmation_question")
        section_id = schema.get_section_id_for_block_id(
            "confirm-zero-employees-block")

        # All blocks completed
        progress_store = ProgressStore([{
            "section_id":
            "default-section",
            "list_item_id":
            None,
            "status":
            CompletionStatus.COMPLETED,
            "block_ids": [
                "number-of-employees-total-block",
                "confirm-zero-employees-block",
            ],
        }])

        answer_store = AnswerStore()
        number_of_employees_answer = Answer(
            answer_id="number-of-employees-total", value=0)
        confirm_zero_answer = Answer(answer_id="confirm-zero-employees-answer",
                                     value="No I need to change this")
        answer_store.add_or_update(number_of_employees_answer)
        answer_store.add_or_update(confirm_zero_answer)

        path_finder = PathFinder(schema, answer_store, self.list_store,
                                 progress_store, self.metadata)

        self.assertEqual(
            len(
                path_finder.progress_store.get_completed_block_ids(
                    section_id="default-section")),
            2,
        )
        self.assertEqual(len(path_finder.answer_store), 2)

        routing_path = path_finder.routing_path(section_id=section_id)

        expected_path = RoutingPath(
            [
                "number-of-employees-total-block",
                "confirm-zero-employees-block",
                "number-of-employees-total-block",
            ],
            section_id="default-section",
        )
        self.assertEqual(routing_path, expected_path)

        self.assertEqual(
            path_finder.progress_store.get_completed_block_ids(
                section_id="default-section"),
            [
                progress_store.get_completed_block_ids(
                    section_id="default-section")[0]
            ],
        )
        self.assertEqual(len(path_finder.answer_store), 1)
def test_transform_variants_list_collector(list_collector_variant_schema):
    schema = QuestionnaireSchema(list_collector_variant_schema)
    answer_store = AnswerStore({})
    answer_store.add_or_update(Answer(answer_id="when-answer", value="no"))
    metadata = {}
    response_metadata = {}

    block = schema.get_block("block1")
    section_id = schema.get_section_id_for_block_id(block["id"])

    transformed_block = transform_variants(
        block,
        schema,
        metadata,
        response_metadata,
        answer_store,
        ListStore({}),
        Location(section_id=section_id, block_id=block["id"]),
    )

    compare_transformed_block(
        block["add_block"], transformed_block["add_block"], "Add, No"
    )
    compare_transformed_block(
        block["remove_block"], transformed_block["remove_block"], "Remove, No"
    )
    compare_transformed_block(
        block["edit_block"], transformed_block["edit_block"], "Edit, No"
    )

    answer_store.add_or_update(Answer(answer_id="when-answer", value="yes"))

    transformed_block = transform_variants(
        block,
        schema,
        metadata,
        response_metadata,
        answer_store,
        ListStore({}),
        Location(section_id=section_id, block_id=block["id"]),
    )

    compare_transformed_block(
        block["add_block"], transformed_block["add_block"], "Add, Yes"
    )
    compare_transformed_block(
        block["remove_block"], transformed_block["remove_block"], "Remove, Yes"
    )
    compare_transformed_block(
        block["edit_block"], transformed_block["edit_block"], "Edit, Yes"
    )
    def test_multi_calculation(self):
        store = AnswerStore()

        answer_total = Answer(answer_id="total-answer", value=10)

        store.add_or_update(answer_total)

        with self.app_request_context():
            schema = load_schema_from_name("test_sum_multi_validation_against_total")

            question_schema = schema.get_block("breakdown-block").get("question")

            form_data = MultiDict(
                {
                    "breakdown-1": "",
                    "breakdown-2": "",
                    "breakdown-3": "",
                    "breakdown-4": "",
                }
            )

            # With no answers question validation should pass
            form = generate_form(
                schema, question_schema, store, metadata=None, form_data=form_data
            )
            form.validate()

            self.assertEqual(len(form.question_errors), 0)

            # With the data equaling the total question validation should pass
            form_data["breakdown-1"] = "10"

            form = generate_form(
                schema, question_schema, store, metadata=None, form_data=form_data
            )
            form.validate()

            self.assertEqual(len(form.question_errors), 0)

            # With the data not equaling zero or the total, question validation should fail
            form_data["breakdown-1"] = "1"

            form = generate_form(
                schema, question_schema, store, metadata=None, form_data=form_data
            )
            form.validate()

            self.assertEqual(
                form.question_errors["breakdown-question"],
                schema.error_messages["TOTAL_SUM_NOT_EQUALS"] % {"total": "10"},
            )
def test_get_referenced_offset_value_for_answer_id(
    app, value_source_resolver, rule_evaluator
):
    answer_store = AnswerStore()

    test_answer_id = Answer(answer_id="date", value="2018-03-20")
    answer_store.add_or_update(test_answer_id)
    value_source_resolver.answer_store = answer_store
    answer = {"maximum": {"value": {"identifier": "date", "source": "answers"}}}

    handler = DateHandler(answer, value_source_resolver, rule_evaluator, error_messages)
    maximum_date = handler.get_date_value("maximum")
    maximum_date = handler.transform_date_by_offset(maximum_date, {"months": 1})

    assert maximum_date == parse_datetime("2018-04-20")
    def test_build_path_with_group_routing(self):
        # Given i have answered the routing question
        schema = load_schema_from_name("test_routing_group")
        section_id = schema.get_section_id_for_block_id("group2-block")

        answer_store = AnswerStore()
        answer_store.add_or_update(
            Answer(answer_id="which-group-answer", value="group2"))

        # When i build the path
        path_finder = PathFinder(schema, answer_store, self.list_store,
                                 self.progress_store, self.metadata)
        path = path_finder.routing_path(section_id=section_id)

        # Then it should route me straight to Group2 and not Group1
        self.assertNotIn("group1-block", path)
        self.assertIn("group2-block", path)