Skip to content
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

Merged
merged 18 commits into from
Aug 20, 2020
Merged

Request IR by Post from Hub #238

merged 18 commits into from
Aug 20, 2020

Conversation

iwootten
Copy link
Contributor

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

  • New static content marked up for translation

@iwootten iwootten force-pushed the request-hub-post-response branch from 7abc92b to d9af537 Compare August 14, 2020 13:28
Copy link
Contributor

@LJBabbage LJBabbage left a 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":
Copy link
Contributor

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

Copy link
Contributor Author

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.

def get_individual_response_who(schema, questionnaire_store):
language_code = get_session_store().session_data.language_code

member_selector_handler = IndividualResponseWhoHandler(
Copy link
Contributor

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.

@@ -41,6 +44,26 @@ class HubContext(Context):
},
}

def __init__(
Copy link
Contributor

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


if count_household_members == 0:
return False

if count_household_members == 1 and self._list_store[for_list].primary_person:
if (
Copy link
Contributor

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(
Copy link
Contributor

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):
Copy link
Contributor

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.

Copy link
Contributor Author

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 = {
Copy link
Contributor

@LJBabbage LJBabbage Aug 16, 2020

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
Copy link
Contributor

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
Copy link
Contributor

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")
Copy link
Contributor

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?

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")
Copy link
Contributor

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"])
Copy link
Contributor

@MebinAbraham MebinAbraham Aug 17, 2020

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?.
  • 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.

Hopefully that is clear, if not, happy to discuss further.

Copy link
Contributor Author

@iwootten iwootten Aug 17, 2020

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?

Copy link
Contributor

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 😄

Copy link
Contributor

@MebinAbraham MebinAbraham left a 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.

Comment on lines 238 to 243
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":
Copy link
Contributor

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.

Comment on lines 249 to 257
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:
Copy link
Contributor

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.

Copy link
Contributor Author

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?

Copy link
Contributor

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.

Copy link
Contributor Author

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.

Comment on lines 159 to 164
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"))
Copy link
Contributor

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.

templates/hub.html Outdated Show resolved Hide resolved
@pricem14pc pricem14pc added this to the v3.48.0 milestone Aug 19, 2020
Copy link
Contributor

@MebinAbraham MebinAbraham left a 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.

Comment on lines 166 to 172
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:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

app/data_model/list_store.py Outdated Show resolved Hide resolved
Comment on lines 184 to 188
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
):
Copy link
Contributor

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

Comment on lines 166 to 170
non_primary_members = []

for list_item in list_model.items:
if list_item != list_model.primary_person:
non_primary_members.append(list_item)
Copy link
Contributor

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.

Comment on lines 142 to 150
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,
)
Copy link
Contributor

@MebinAbraham MebinAbraham Aug 20, 2020

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")

Copy link
Contributor

@MebinAbraham MebinAbraham left a 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. 👍

@iwootten iwootten merged commit 9f8415c into master Aug 20, 2020
@iwootten iwootten deleted the request-hub-post-response branch August 20, 2020 15:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants