-
Notifications
You must be signed in to change notification settings - Fork 14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Request IR by Post from Hub #238
Conversation
7abc92b
to
d9af537
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Works as expected, a few minor points, nothing major
@@ -63,10 +65,10 @@ def request_individual_response(schema, questionnaire_store): | |||
list_item_id=list_item_id, | |||
) | |||
|
|||
if request.method == "GET": | |||
return individual_response_handler.handle_get() | |||
if request.method == "POST": |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I couldn't immediate see a reason for it to change to POST, I am sure there must be. I only raise it as in other routes we usually do GET first
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The default fallback option should really always be the call to the get. The only other place I can see this is 3 cases in questionnaire.py, where the logic on the get condition is confusing because it involves a call to the post form. They should probably be changed too.
app/routes/individual_response.py
Outdated
def get_individual_response_who(schema, questionnaire_store): | ||
language_code = get_session_store().session_data.language_code | ||
|
||
member_selector_handler = IndividualResponseWhoHandler( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reading the card I understand why you have called it member_selector_handler, just looks a little odd with all the others called individual_response_handler(not sure this is right either) and the name of your handler. I think either we name all of them better or be consistent across all of them.
app/views/contexts/hub_context.py
Outdated
@@ -41,6 +44,26 @@ class HubContext(Context): | |||
}, | |||
} | |||
|
|||
def __init__( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for_list is only used in _individual_response_enabled as far as I can tell, so I am not sure it needs to be add to the init just _individual_response_enabled, which naturally means we could get rid of the whole init .
Also once in there you could get rid of the if statement as its already checked
app/views/contexts/hub_context.py
Outdated
|
||
if count_household_members == 0: | ||
return False | ||
|
||
if count_household_members == 1 and self._list_store[for_list].primary_person: | ||
if ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be worth putting it on one line
if count_household_members == 0 or (
count_household_members == 1 and self._list_stor[for_list].primary_person
):
return False
@@ -225,16 +237,19 @@ def __init__( | |||
) | |||
|
|||
def handle_get(self): | |||
previous_location_url = url_for( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than call url_for potentially twice, perhaps just else the return_to_hub?
return self.form.get_data(answer_id) | ||
|
||
@cached_property | ||
def selected_list_item(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very minor, but I would absorb selected_option in here, I understood what select_list_item meant without the extra method and with it not being used anywhere else I feel it could sit as one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the approach adopted in the previous class, I think it's clearer to separate them.
) | ||
) | ||
|
||
self.people_names = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we lose a bit of context with the var name, when I got to the handle_get and looking at len(self.people_names) > 1 I couldn't tell if this included primary or not. On checking back I can see its has been removed, the name should perhaps reflect that
self.assertInUrl("/how") | ||
|
||
def test_goes_to_who_selector(self): | ||
# Given I add a household member |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2 household members / or just members
self.assertInUrl("/who") | ||
|
||
def test_previous_returns_to_hub(self): | ||
# Given I add a household member |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above
|
||
class IndividualResponseWhoHandler(IndividualResponseHandler): | ||
def __init__(self, schema, questionnaire_store, language, request_args, form_data): | ||
self._list_name = schema.json.get("individual_response", {}).get("for_list") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As we are calling schema.json.get("individual_response", {}) a few times now, would it be best to have its own method in QuestionnaireSchema?
app/views/contexts/hub_context.py
Outdated
count_household_members = len(self._list_store[self._for_list]) | ||
for_list = ( | ||
self._schema.json["individual_response"]["for_list"] | ||
if self._schema.json.get("individual_response") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At this stage you know individual_response is true, due to the if above it
) | ||
|
||
|
||
@individual_response_blueprint.route("/who", methods=["GET", "POST"]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The previous link for this journey should back to the previous page. It should only go to the hub when on you are back on the IR request launcher
page.
Scenarios:
-
1 non-primary person only:
- The previous link on the how page is also adding list item id to the url which is taking it back to the individual section from
IR request launcher
page instead of the hub. Regardless of the number of people, the previous should go back to the hub if we know they came from the hub?.
- The previous link on the how page is also adding list item id to the url which is taking it back to the individual section from
-
at least 2 non-primary person
- The previous link from any IR page is going straight to the hub, instead of back sequentially to the
IR request launcher
page then the hub.
- The previous link from any IR page is going straight to the hub, instead of back sequentially to the
Hopefully that is clear, if not, happy to discuss further.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the card has overstated this somewhat which has made it confusing "Previous link should always go back to hub no matter how far along the IR journey you are (ensure alternate journey goes to individual section introduction page)."
In all honesty, I'm not sure why the this requirement was specified as it would be the expected behaviour?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that comment has overstated it @iwootten - I think it was added to differentiate between the hub originated journey and the individual section originated journey, but that would be default behaviour as you pointed out 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apart from the previous journey, the feature to select who to request IR for is working as expected.
if self._return_to_hub: | ||
previous_location_url = url_for( | ||
"individual_response.get_individual_response_change", | ||
list_item_id=self._list_item_id, | ||
"individual_response.get_individual_response_who", | ||
return_to=self._return_to, | ||
) | ||
else: | ||
elif self._request_args.get("journey") == "change": |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should use journey
instead of return_to
when the immediate page isn't the return to location. return to makes sense if the next page or previous page would be the return to page, but journey
was recently introduced to track the journey between multiple screens.
self._list_name = self._schema.get_individual_response_list() | ||
list_model = self._questionnaire_store.list_store[self._list_name] | ||
non_primary_members = 0 | ||
|
||
for list_item in list_model.items: | ||
if list_item != list_model.primary_person: | ||
non_primary_members += 1 | ||
|
||
if non_primary_members > 1: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't needed if we persist the request args, because that would tell you if you came from the hub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is able to be edited though?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean the query param can be edited?. If so, yes but that shouldn't matter as long as it is one of the ones we are expecting, as we need to handle that scenario anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As discussed offline, it's likely this logic doesn't belong in this handler if we skip over it when there is only a single member.
def handle_post(self): | ||
if self._list_item_id: | ||
return redirect( | ||
url_for(".get_individual_response_how", list_item_id=self._list_item_id) | ||
) | ||
return redirect(url_for(".get_individual_response_who", return_to="hub")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At the moment, when there is only 1 non-primary person, this is redirecting to the who route which then redirects to how route, but we should be avoiding that extra redirect as we can work out at this point whether to go to the who route or the how route based on the count of non-primary list items.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The previous links are not working correctly. If you go to the request IR page, the previous goes to a 404 page. If you step forward to the how screen, then clicking previous twice goes back to the individual section even though for both journeys I started from the hub.
non_primary_members = [] | ||
|
||
for list_item in list_model.items: | ||
if list_item != list_model.primary_person: | ||
non_primary_members.append(list_item) | ||
|
||
if len(non_primary_members) == 1: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should have a property on list model to return the non primary list item ids. Which can then be reused here, as well as in:
app/views/contexts/hub_context.py
Outdated
count_household_members = len(self._list_store[for_list]) | ||
|
||
if count_household_members == 0: | ||
return False | ||
|
||
if count_household_members == 1 and self._list_store[for_list].primary_person: | ||
if count_household_members == 0 or ( | ||
count_household_members == 1 and self._list_store[for_list].primary_person | ||
): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can now be simplied to:
if not self._list_store[for_list].non_primary_people:
return False
non_primary_members = [] | ||
|
||
for list_item in list_model.items: | ||
if list_item != list_model.primary_person: | ||
non_primary_members.append(list_item) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be replaced by list_model.non_primary_people
.
Co-authored-by: Mebin Abraham <[email protected]>
if self._is_hub_journey: | ||
previous_location_url = url_for("questionnaire.get_questionnaire") | ||
else: | ||
previous_location_url = url_for( | ||
"questionnaire.block", | ||
list_name=self._list_name, | ||
list_item_id=self._list_item_id, | ||
block_id=individual_section_first_block_id, | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This logic means if you manually visit the url, which is possible, you would get a 404 because there is no query param for list item id. Therefore, we should by default go to the hub if there is no query param. Right now it would be safe to assume if there is no list item id, then you should go to the hub. So it could be:
if self._list_item_id:
previous_location_url = url_for(
"questionnaire.block",
list_name=self._list_name,
list_item_id=self._list_item_id,
block_id=individual_section_first_block_id,
)
else:
previous_location_url = url_for("questionnaire.get_questionnaire")
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apart from my last comment, everything seems to be as expected. 👍
What is the context of this PR?
Added a person selector to the individual response. The selector is only shown when requested via the hub and 2 or more non-primary householders exist. The selector is skipped on paths from the hub where conditions aren't met.
How to review
Check to see if you agree with the approach.
Checklist