Skip to content

Commit

Permalink
Add initial support for unrelated relationship (#339)
Browse files Browse the repository at this point in the history
  • Loading branch information
MebinAbraham authored Oct 9, 2020
1 parent c7176b6 commit 12a6cfd
Show file tree
Hide file tree
Showing 13 changed files with 733 additions and 17 deletions.
15 changes: 11 additions & 4 deletions app/questionnaire/questionnaire_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
"PrimaryPersonListAddOrEditQuestion",
]

RELATIONSHIP_CHILDREN = ["UnrelatedQuestion"]


class QuestionnaireSchema: # pylint: disable=too-many-public-methods
def __init__(self, questionnaire_json, language_code=DEFAULT_LANGUAGE_CODE):
Expand Down Expand Up @@ -90,12 +92,17 @@ def _get_blocks_by_id(self):
self._parent_id_map[block_id] = group["id"]

blocks[block_id] = block
if block["type"] in ("ListCollector", "PrimaryPersonListCollector"):
if block["type"] in (
"ListCollector",
"PrimaryPersonListCollector",
"RelationshipCollector",
):
for nested_block_name in [
"add_block",
"edit_block",
"remove_block",
"add_or_edit_block",
"unrelated_block",
]:
if block.get(nested_block_name):
nested_block = block[nested_block_name]
Expand Down Expand Up @@ -244,8 +251,8 @@ def get_custom_page_title_for_section(self, section_id):
def get_section_for_block_id(self, block_id):
block = self.get_block(block_id)

if block.get("type") in LIST_COLLECTOR_CHILDREN:
section_id = self._get_section_id_for_list_block(block_id)
if block.get("type") in LIST_COLLECTOR_CHILDREN + RELATIONSHIP_CHILDREN:
section_id = self._get_parent_section_id_for_block(block_id)
else:
group_id = self._parent_id_map[block_id]
section_id = self._parent_id_map[group_id]
Expand Down Expand Up @@ -467,7 +474,7 @@ def is_question_block_type(block_type):
"ConfirmationQuestion",
]

def _get_section_id_for_list_block(self, block_id):
def _get_parent_section_id_for_block(self, block_id):
parent_block_id = self._parent_id_map[block_id]
group_id = self._parent_id_map[parent_block_id]
section_id = self._parent_id_map[group_id]
Expand Down
4 changes: 2 additions & 2 deletions app/questionnaire/relationship_location.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ def for_json(self) -> Mapping:

def url(self, **kwargs) -> str:
return url_for(
"questionnaire.relationship",
block_id=self.block_id,
"questionnaire.relationships",
list_name=self.list_name,
list_item_id=self.list_item_id,
to_list_item_id=self.to_list_item_id,
**kwargs,
Expand Down
8 changes: 5 additions & 3 deletions app/questionnaire/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ def enabled_section_ids(self):
if self._is_section_enabled(section=section)
]

def is_list_item_in_list_store(self, list_item_id, list_name):
return list_item_id in self._list_store[list_name]

def can_access_location(self, location: Location, routing_path):
"""
Checks whether the location is valid and accessible.
Expand All @@ -38,9 +41,8 @@ def can_access_location(self, location: Location, routing_path):
if location.section_id not in self.enabled_section_ids:
return False

if (
location.list_item_id
and location.list_item_id not in self._list_store[location.list_name]
if location.list_item_id and not self.is_list_item_in_list_store(
location.list_item_id, location.list_name
):
return False

Expand Down
17 changes: 14 additions & 3 deletions app/routes/questionnaire.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,20 +223,31 @@ def block(schema, questionnaire_store, block_id, list_name=None, list_item_id=No


@questionnaire_blueprint.route(
"<block_id>/<list_item_id>/to/<to_list_item_id>/", methods=["GET", "POST"]
"relationships/<list_name>/<list_item_id>/to/<to_list_item_id>/",
methods=["GET", "POST"],
)
@questionnaire_blueprint.route(
"relationships/<list_name>/<list_item_id>/<block_id>/", methods=["GET", "POST"]
)
@with_questionnaire_store
@with_schema
def relationship(schema, questionnaire_store, block_id, list_item_id, to_list_item_id):
def relationships(
schema,
questionnaire_store,
list_name,
list_item_id,
to_list_item_id=None,
block_id="relationships",
):
try:
block_handler = get_block_handler(
schema=schema,
block_id=block_id,
list_item_id=list_item_id,
to_list_item_id=to_list_item_id,
questionnaire_store=questionnaire_store,
list_name=list_name,
language=flask_babel.get_locale().language,
list_name=schema.get_block(block_id)["for_list"],
request_args=request.args,
form_data=request.form,
)
Expand Down
5 changes: 3 additions & 2 deletions app/views/handlers/block_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from app.views.handlers.primary_person_list_collector import PrimaryPersonListCollector
from app.views.handlers.primary_person_question import PrimaryPersonQuestion
from app.views.handlers.question import Question
from app.views.handlers.relationship_collector import RelationshipCollector
from app.views.handlers.relationships import RelationshipCollector, UnrelatedQuestion
from app.views.handlers.summary import Summary

BLOCK_MAPPINGS = {
Expand All @@ -23,6 +23,7 @@
"PrimaryPersonListCollector": PrimaryPersonListCollector,
"PrimaryPersonListAddOrEditQuestion": PrimaryPersonQuestion,
"RelationshipCollector": RelationshipCollector,
"UnrelatedQuestion": UnrelatedQuestion,
"Introduction": Content,
"Interstitial": Content,
"Confirmation": Content,
Expand Down Expand Up @@ -63,7 +64,7 @@ def get_block_handler(

section_id = schema.get_section_id_for_block_id(block_id)

if to_list_item_id:
if to_list_item_id or block_type == "UnrelatedQuestion":
location = RelationshipLocation(
section_id=section_id,
block_id=block_id,
Expand Down
4 changes: 4 additions & 0 deletions app/views/handlers/relationships/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from .relationship_collector import RelationshipCollector
from .unrelated_question import UnrelatedQuestion

__all__ = ["RelationshipCollector", "UnrelatedQuestion"]
45 changes: 45 additions & 0 deletions app/views/handlers/relationships/unrelated_question.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from app.questionnaire.location import Location
from app.views.handlers.question import Question


class UnrelatedQuestion(Question):
def _get_parent_list_name(self):
parent_block_id = self._schema.parent_id_map[self.block["id"]]
return self._schema.get_block(parent_block_id)["for_list"]

@property
def parent_location(self):
parent_block_id = self._schema.parent_id_map[self.block["id"]]
return Location(
section_id=self._current_location.section_id, block_id=parent_block_id
)

def _get_routing_path(self):
return self.router.routing_path(section_id=self.parent_location.section_id)

def is_location_valid(self):
can_access_parent_location = self.router.can_access_location(
self.parent_location, self._routing_path
)

if not can_access_parent_location:
return False

if self.current_location.list_name != self._get_parent_list_name() or (
self.current_location.list_item_id
and not self.router.is_list_item_in_list_store(
self.current_location.list_item_id, self.current_location.list_name
)
):
return False

return True

def get_previous_location_url(self):
pass

def get_next_location_url(self):
pass # pragma: no cover

def handle_post(self):
pass # pragma: no cover
1 change: 1 addition & 0 deletions templates/unrelatedquestion.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{% include 'question.html' %}
Loading

0 comments on commit 12a6cfd

Please sign in to comment.