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

endline validation #649

Merged
merged 4 commits into from
Aug 1, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 29 additions & 2 deletions yal/main.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import asyncio
import logging
import random

from vaccine.models import Message
from vaccine.states import Choice, EndState, WhatsAppButtonState
from vaccine.states import Choice, EndState, FreeText, WhatsAppButtonState
from vaccine.utils import get_display_choices, random_id
from yal import rapidpro, utils
from yal.askaquestion import Application as AaqApplication
Expand Down Expand Up @@ -202,6 +203,7 @@ async def process_message(self, message):
)

endline_survey_started = self.user.metadata.get("endline_survey_started")
endline_reminder = self.user.metadata.get("endline_reminder")

if (
keyword in EJAF_ENDLINE_SURVEY_KEYWORDS
Expand All @@ -215,7 +217,7 @@ async def process_message(self, message):
self.user.session_id = None
self.state_name = AssessmentApplication.REMINDER_STATE
elif keyword == "i m not interested":
if endline_survey_started:
if endline_reminder:
self.user.session_id = None
self.state_name = (
AssessmentApplication.REMINDER_NOT_INTERESTED_STATE
Expand All @@ -227,6 +229,10 @@ async def process_message(self, message):
self.user.session_id = None
self.state_name = EndlineTermsApplication.START_STATE

if endline_survey_started and not self.state_name:
self.user.session_id = None
self.state_name = "state_survey_validation"

# Fields that RapidPro sets after a feedback push message
feedback_state = await self.get_feedback_state()
if feedback_state:
Expand Down Expand Up @@ -855,3 +861,24 @@ async def publish_message(self, question):
"""
content = replace_persona_fields(question, self.user.metadata)
await self.worker.publish_message(self.inbound.reply(content))

async def state_survey_validation(self):
"""
Copy link
Contributor

Choose a reason for hiding this comment

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

Is main.py the right place for this state? It's very survey specific so maybe it should live there?

Validates survey keywords from RapidPro
"""

GENERIC_ERRORS = (
Copy link
Contributor

Choose a reason for hiding this comment

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

Can't we import these from the other place they are defined?

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 wording is different

"Oh oh 👀, I don't understand your reply. But don't worry, we can "
"try again. This time, please reply with the option that matches "
"your choice.👍🏾",
"Oops, looks like I don't have that option available.🤔 Please "
"try again - I'll get it if you use the option that matches your "
"choice, promise.👍🏾",
"Umm...I'm sorry but I'm not sure what that means "
"[persona_emoji]👩🏾. You can help me by trying again. This time, "
"look for the option matching your choice and send that👍🏾",
)

random_error = random.choice(GENERIC_ERRORS)

return FreeText(self, question=random_error, next=None)
4 changes: 4 additions & 0 deletions yal/surveys/endline.py
Original file line number Diff line number Diff line change
Expand Up @@ -425,8 +425,12 @@ async def state_submit_endline_completed(self):
"endline_survey_completed": "True",
"ejaf_endline_airtime_incentive_sent": "False",
"ejaf_endline_completed_on": get_current_datetime().isoformat(),
"endline_survey_started": "",
"endline_reminder": "",
}
self.save_answer("endline_survey_completed", "True")
self.save_answer("endline_survey_started", "False")
self.save_answer("endline_reminder", "False")

error = await rapidpro.update_profile(whatsapp_id, data, self.user.metadata)
if error:
Expand Down
1 change: 1 addition & 0 deletions yal/tests/states_dictionary.md
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@
| state_reschedule_assessment_reminder | | | | Schedules the assessment reminders |
| state_remind_tomorrow | TRUE | Text | TRUE | Lets the user know we will remind them tomorrow, asks the user if they would like to go to the mainmenu |
| state_reminder_not_interested | True | Text | TRUE | Lets the user know that they will no longer be prt of the study |
| state_survey_validation | True | Text | TRUE | endline survey catch all validation |


### Service finder flow
Expand Down
25 changes: 24 additions & 1 deletion yal/tests/surveys/test_endline.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ async def test_endline_reminder_not_interested(
addr="278201234567",
state=StateData(),
session_id=1,
metadata={"baseline_survey_completed": True, "endline_survey_started": True},
metadata={"baseline_survey_completed": True, "endline_reminder": True},
)
app = Application(user)
msg = Message(
Expand Down Expand Up @@ -191,6 +191,29 @@ async def test_endline_invitation_answer(tester: AppTester, rapidpro_mock):
assert user.state.name == "state_start_terms"


@pytest.mark.asyncio
async def test_endline_survey_validation(tester: AppTester, rapidpro_mock):

user = User(
addr="278201234567",
state=StateData(),
session_id=1,
metadata={"baseline_survey_completed": True, "endline_survey_started": True},
)
app = Application(user)
msg = Message(
content="this is wrong input",
to_addr="27820001002",
from_addr="27820001003",
transport_name="whatsapp",
transport_type=Message.TRANSPORT_TYPE.HTTP_API,
)

[reply] = await app.process_message(msg)

assert user.state.name == "state_survey_validation"


@pytest.mark.asyncio
async def test_state_platform_review_endline(tester: AppTester, rapidpro_mock):
await tester.user_input(
Expand Down
Loading