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"
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_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")
Ejemplo n.º 4
0
def test_unique_id_generation():
    """
    Ensure that every id generated is unique per questionnaire.
    """
    # Mock the app.data_model.list_store.random_string method to return duplicates.
    with patch(
        "app.data_model.list_store.random_string",
        side_effect=["first", "first", "second"],
    ):
        list_store = ListStore()
        # pylint: disable=protected-access
        list_store._lists["test"] = ListModel(name="test", items=["first"])
        result = list_store._generate_identifier()

    assert result == "second"
Ejemplo n.º 5
0
    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 fake_list_store():
    serialised = [
        {"name": "people", "primary_person": "abcdef", "items": ["abcdef", "xyzabc"]},
        {"name": "pets", "items": ["tuvwxy"]},
    ]

    return ListStore.deserialise(serialised)
    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 setUp(self):
     super().setUp()
     self.schema = load_schema_from_name("test_section_summary")
     self.answer_store = AnswerStore()
     self.list_store = ListStore()
     self.progress_store = ProgressStore()
     self.block_type = "SectionSummary"
Ejemplo n.º 9
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,
            ))
Ejemplo n.º 10
0
def test_context_for_driving_question_summary_empty_list():
    schema = load_schema_from_name("test_list_collector_driving_question")
    current_location = Location(block_id="summary", section_id="section")

    list_collector_summary_context = ListCollectorSummaryContext(
        DEFAULT_LANGUAGE_CODE,
        schema,
        AnswerStore([{"answer_id": "anyone-usually-live-at-answer", "value": "No"}]),
        ListStore(),
        ProgressStore(),
        {},
    )

    context = list_collector_summary_context.get_list_summaries(current_location)

    expected = [
        {
            "add_link": "/questionnaire/anyone-usually-live-at/",
            "add_link_text": "Add someone to this household",
            "empty_list_text": "There are no householders",
            "title": "Household members",
            "list_name": "people",
        }
    ]

    assert context == expected
 def _deserialise(self, data):
     json_data = json.loads(data, use_decimal=True)
     self.progress_store = ProgressStore(json_data.get("PROGRESS"))
     self.set_metadata(json_data.get("METADATA", {}))
     self.answer_store = AnswerStore(json_data.get("ANSWERS"))
     self.list_store = ListStore.deserialise(json_data.get("LISTS"))
     self.collection_metadata = json_data.get("COLLECTION_METADATA", {})
Ejemplo n.º 12
0
    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,
            ))
Ejemplo n.º 13
0
def test_renders_text_plural_from_list():
    renderer = PlaceholderRenderer(language="en",
                                   list_store=ListStore(),
                                   schema=Mock())

    rendered_text = renderer.render_placeholder(
        {
            "text_plural": {
                "forms": {
                    "one": "Yes, {number_of_people} person lives here",
                    "other": "Yes, {number_of_people} people live here",
                },
                "count": {
                    "source": "list",
                    "identifier": "household"
                },
            },
            "placeholders": [{
                "placeholder": "number_of_people",
                "value": {
                    "source": "list",
                    "identifier": "household"
                },
            }],
        },
        None,
    )

    assert rendered_text == "Yes, 0 people live here"
Ejemplo n.º 14
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,
            ))
Ejemplo n.º 15
0
    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,
            ))
Ejemplo n.º 16
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,
            ))
Ejemplo n.º 17
0
def test_default_answers_not_present_when_not_answered(
        fake_questionnaire_store):
    """Test that default values aren't submitted downstream when an answer with
    a default value is not present in the answer store."""
    schema = load_schema("test_view_submitted_response")

    answer_objects = [
        {
            "answer_id": "test-currency",
            "value": "12"
        },
        {
            "answer_id": "square-kilometres",
            "value": "345"
        },
        {
            "answer_id": "test-decimal",
            "value": "67.89"
        },
    ]

    fake_questionnaire_store.answer_store = AnswerStore(answer_objects)
    fake_questionnaire_store.list_store = ListStore()

    routing_path = [
        RoutingPath(["radio", "test-number-block"],
                    section_id="default-section")
    ]

    output = convert_answers(schema, fake_questionnaire_store, routing_path)
    data = json.loads(json.dumps(output["data"]["answers"], for_json=True))

    answer_ids = {answer["answer_id"] for answer in data}
    assert "radio-answer" not in answer_ids
Ejemplo n.º 18
0
    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,
            ))
Ejemplo n.º 19
0
def test_list_source_count():
    placeholder_list = [{
        "placeholder": "number_of_people",
        "value": {
            "source": "list",
            "identifier": "people"
        },
    }]

    list_store = ListStore()
    list_store.add_list_item("people")
    list_store.add_list_item("people")

    parser = PlaceholderParser(language="en", list_store=list_store)
    placeholders = parser(placeholder_list)

    assert placeholders["number_of_people"] == 2
Ejemplo n.º 20
0
    def test_evaluate_goto_returns_false_when_checkbox_question_not_answered(
            self):

        goto_contains = {
            "id":
            "next-question",
            "when": [{
                "id": "my_answers",
                "condition": "contains",
                "value": "answer1"
            }],
        }

        goto_not_contains = {
            "id":
            "next-question",
            "when": [{
                "id": "my_answers",
                "condition": "not contains",
                "value": "answer1"
            }],
        }
        answer_store = AnswerStore()

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

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

        self.assertFalse(
            evaluate_goto(
                goto_rule=goto_not_contains,
                schema=get_schema(),
                metadata={},
                answer_store=answer_store,
                list_store=ListStore(),
                current_location=current_location,
            ))
    def __init__(self, storage, version=None):
        self._storage = storage
        if version is None:
            version = self.get_latest_version_number()
        self.version = version
        self._metadata = {}
        # self.metadata is a read-only view over self._metadata
        self.metadata = MappingProxyType(self._metadata)
        self.collection_metadata = {}
        self.list_store = ListStore()
        self.answer_store = AnswerStore()
        self.progress_store = ProgressStore()

        raw_data, version = self._storage.get_user_data()
        if raw_data:
            self._deserialise(raw_data)
        if version is not None:
            self.version = version
Ejemplo n.º 22
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,
                ))
Ejemplo n.º 23
0
def get_view_submission(schema):

    session_data = get_session_store().session_data

    if _is_submission_viewable(schema.json, session_data.submitted_time):
        submitted_data = current_app.eq["storage"].get_by_key(
            SubmittedResponse, session_data.tx_id
        )

        if submitted_data:

            metadata_context = build_metadata_context_for_survey_completed(session_data)

            pepper = current_app.eq["secret_store"].get_secret_by_name(
                "EQ_SERVER_SIDE_STORAGE_ENCRYPTION_USER_PEPPER"
            )

            encrypter = StorageEncryption(
                current_user.user_id, current_user.user_ik, pepper
            )
            submitted_data = encrypter.decrypt_data(submitted_data.data)

            # for backwards compatibility
            # submitted data used to be base64 encoded before encryption
            try:
                submitted_data = base64url_decode(submitted_data.decode()).decode()
            except ValueError:
                pass

            submitted_data = json.loads(submitted_data)
            answer_store = AnswerStore(submitted_data.get("answers"))
            list_store = ListStore(submitted_data.get("lists"))
            progress_store = ProgressStore(submitted_data.get("progress"))

            metadata = submitted_data.get("metadata")
            language_code = get_session_store().session_data.language_code
            questionnaire_summary_context = QuestionnaireSummaryContext(
                language_code,
                schema,
                answer_store,
                list_store,
                progress_store,
                metadata,
            )

            context = questionnaire_summary_context(answers_are_editable=False)

            return render_template(
                template="view-submission",
                metadata=metadata_context,
                content=context,
                survey_id=schema.json["survey_id"],
            )

    return redirect(url_for("post_submission.get_thank_you"))
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 = {}

    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["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,
        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")
Ejemplo n.º 25
0
def test_list_item_conversion_empty_list(fake_questionnaire_store):
    """ Test that the list store is populated with an empty list for lists which
    do not have answers yet."""
    routing_path = [
        RoutingPath(
            [
                "list-collector",
                "next-interstitial",
                "another-list-collector-block",
                "group-summary",
            ],
            section_id="section-1",
        )
    ]

    answer_objects = [
        {
            "answer_id": "last-name",
            "value": "2",
            "list_item_id": "RfAGDc"
        },
        {
            "answer_id": "anyone-else",
            "value": "No"
        },
        {
            "answer_id": "another-anyone-else",
            "value": "No"
        },
        {
            "answer_id": "extraneous-answer",
            "value": "Bad",
            "list_item_id": "123"
        },
    ]

    fake_questionnaire_store.answer_store = AnswerStore(answer_objects)
    fake_questionnaire_store.list_store = ListStore()

    schema = load_schema("test_list_collector")

    output = convert_answers(schema, fake_questionnaire_store, routing_path)

    # Answers not on the routing path
    del answer_objects[0]
    del answer_objects[-1]

    data_dict = json.loads(json.dumps(output["data"]["answers"],
                                      for_json=True))

    assert sorted(answer_objects, key=lambda x: x["answer_id"]) == sorted(
        data_dict, key=lambda x: x["answer_id"])
Ejemplo n.º 26
0
def test_delete_list_item_id_does_not_raise():
    store = ListStore()
    store.add_list_item("people")
    try:
        store.delete_list_item("people", "123456")
    except ValueError:
        # Not necessary, but keeps it explicit.
        pytest.fail("Deleting a non-existant list item raised an error")
    def test_full_routing_path_with_repeating_sections(self):
        schema = load_schema_from_name(
            "test_repeating_sections_with_hub_and_spoke")

        list_store = ListStore([{
            "items": ["abc123", "123abc"],
            "name": "people",
            "primary_person": "abc123",
        }])

        router = Router(schema, self.answer_store, list_store,
                        self.progress_store, self.metadata)

        routing_path = router.full_routing_path()

        expected_path = [
            RoutingPath(
                [
                    "primary-person-list-collector",
                    "list-collector",
                    "next-interstitial",
                    "another-list-collector-block",
                    "visitors-block",
                ],
                section_id="section",
                list_name=None,
                list_item_id=None,
            ),
            RoutingPath(
                [
                    "proxy", "date-of-birth", "confirm-dob", "sex",
                    "personal-summary"
                ],
                section_id="personal-details-section",
                list_name="people",
                list_item_id="abc123",
            ),
            RoutingPath(
                [
                    "proxy", "date-of-birth", "confirm-dob", "sex",
                    "personal-summary"
                ],
                section_id="personal-details-section",
                list_name="people",
                list_item_id="123abc",
            ),
        ]

        self.assertEqual(routing_path, expected_path)
Ejemplo n.º 28
0
def test_repr():
    test_list = ListModel("people", ["primaryperson"], primary_person="primaryperson")
    serialised = [
        {
            "name": "people",
            "primary_person": "primaryperson",
            "items": ["123", "primaryperson"],
        }
    ]

    list_store = ListStore.deserialise(serialised)

    assert "primary_person=primaryperson" in repr(test_list)
    assert "items=['primaryperson']" in repr(test_list)
    assert "primaryperson" in repr(list_store)
 def setUp(self):
     super().setUp()
     self.schema = load_schema_from_name("test_summary")
     self.answer_store = AnswerStore()
     self.list_store = ListStore()
     self.progress_store = ProgressStore()
     self.block_type = "Summary"
     self.rendered_block = {
         "parent_id": "summary-group",
         "id": "summary",
         "type": "Summary",
         "collapsible": True,
     }
     self.current_location = Location(section_id="default-section",
                                      block_id="summary")
Ejemplo n.º 30
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,
            ))