-
Notifications
You must be signed in to change notification settings - Fork 1
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
feat: add audit gate to CourseChatView #134
Conversation
Reference for modes for audit & verified learners, per the AUDIT_MODES = [ VERIFIED_MODES = [ |
Coverage reportClick to see where and how coverage changed
This report was generated by python-coverage-comment-action |
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.
Looks good so far! Added some comments.
learning_assistant/api.py
Outdated
) | ||
|
||
# If the trial was just created, then it definitely isn't expired, so return False | ||
if created: |
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.
Is it possible that a Trial could be created with 0 days left? For example, if the upgrade deadline has already passed?
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.
If the upgrade deadline has passed, should we prevent them from creating a trial? I think that's what you're suggesting below, but just wanted to echo that here.
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.
Also, in theory, this would depend on the value of AUDIT_TRIAL_MAX_DAYS
. That value could be 0, in which case it's not correct for this to return True
. Because that value is configurable, I don't know that we can say that always returning True
in this case is the right thing to do. I think it would be better to rely on the code that uses the value of AUDIT_TRIAL_MAX_DAYS
. It's a simple computation, so I don't think we lose much by using it in all cases.
learning_assistant/views.py
Outdated
# NOTE: Will there ever be a case where the user has a course mod that's | ||
# in neither VERIFIED_MODES nor AUDIT_MODES that we need to worry about? | ||
enrollment_mode not in CourseMode.VERIFIED_MODES | ||
and enrollment_mode in CourseMode.AUDIT_MODES |
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'm not positive, but the logic here seems to match: https://github.com/openedx/frontend-app-learning/blob/6813872dd3b6737a1a6e13764feb9fa7596cbe3d/src/courseware/course/chat/Chat.jsx#L43. So I think that this should cover it?
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.
If we want to display the learning assistant to audit learners, doesn't that mean we'll need to change that logic in the frontend as well?
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 list of VERIFIED_MODES in the learning MFE is slightly different than the list in the LMS.
I think what is important is that a learner can upgrade from any of the audit modes, right? We'd only want to shower learners than can upgrade the trial. I'm not entirely sure what that exact list is. We may need to figure that 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.
It seems like the VERIFIED_MODES in the learning MFE includes all the modes that are not part of the AUDIT_MODES in the LMS, so I'm wondering we should do one of two things:
- Only check is the user's enrollment mode is in AUDIT_MODES,
- or check that the mode is in frontend-app-learning's version of VERIFIED_MODES.
Kind of leaning towards the first option, but let me know your thoughts.
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 tried to find where we allow learners to upgrade and what modes we allow a learner to be in to upgrade. I can't find a singular place. There is the is_mode_upgradeable method in the LMS, but it's not that widely used.
There is serialize_upgrade_info, which is used by several of the endpoints the learning MFE uses. can_show_verified_upgrade uses is_mode_upsellable, which refers to CourseMode.UPSELL_TO_VERIFIED_MODES
, as does can_show_verified_upgrade
later in teh function. CourseMode.UPSELL_TO_VERIFIED_MODES
is [HONOR, AUDIT]
.
This kind of makes sense to me. I don't know if we enroll can enroll learners in ExecEd and Bootcamps via the usual upgrade process, so it's possible learners in the UNPAID_EXECUTIVE_EDUCATION
, and UNPAID_BOOTCAMP
modes do not see any upgrade messaging.
If that's the case, we may have three states.
- learners in verified modes and staff - full access
- learners in the
audit
andhonor
modes - ability to start trial - learners in other modes - no access
I'm harping on this because I wouldn't want to advertise a feature that a learner cannot access via upgrade. I think this is worth a conversation at tomorrow's stand up. What do you think?
P.S. I would also want to confirm that we want all "verified" modes to have access to Xpert. Do we want Masters users to have access to Xpert, for example?
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 did some digging through the code you linked. Long story short, this seems like what we need (this is a slight modification of what you posted):
- Any learners in verified modes (per the list in the frontend) or staff will have full access.
- Any learners with course modes in CourseMode.UPSELL_TO_VERIFIED_MODES will start or continue their trial (unless it's expired, in which case return 403).
- Learners in all other course modes (captured in an else statement) will get returned 403.
I've just committed changes reflecting this.
learning_assistant/api.py
Outdated
if created: | ||
return False | ||
|
||
# If the user's trial is expired, return True. Else, return False |
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.
Related to above, but we may need to include logic for checking if the course upgrade deadline has passed (unless that's somewhere else, in which case, disregard!)
learning_assistant/api.py
Outdated
|
||
# If the user's trial is expired, return True. Else, return False | ||
DAYS_SINCE_TRIAL_START_DATE = datetime.now() - audit_trial.start_date | ||
if DAYS_SINCE_TRIAL_START_DATE > timedelta(days=AUDIT_TRIAL_MAX_DAYS): |
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 this should be >=
, right?
learning_assistant/api.py
Outdated
) | ||
|
||
# If the trial was just created, then it definitely isn't expired, so return False | ||
if created: |
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.
If the upgrade deadline has passed, should we prevent them from creating a trial? I think that's what you're suggesting below, but just wanted to echo that here.
learning_assistant/api.py
Outdated
) | ||
|
||
# If the trial was just created, then it definitely isn't expired, so return False | ||
if created: |
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.
Also, in theory, this would depend on the value of AUDIT_TRIAL_MAX_DAYS
. That value could be 0, in which case it's not correct for this to return True
. Because that value is configurable, I don't know that we can say that always returning True
in this case is the right thing to do. I think it would be better to rely on the code that uses the value of AUDIT_TRIAL_MAX_DAYS
. It's a simple computation, so I don't think we lose much by using it in all cases.
learning_assistant/views.py
Outdated
# NOTE: Will there ever be a case where the user has a course mod that's | ||
# in neither VERIFIED_MODES nor AUDIT_MODES that we need to worry about? | ||
enrollment_mode not in CourseMode.VERIFIED_MODES | ||
and enrollment_mode in CourseMode.AUDIT_MODES |
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 list of VERIFIED_MODES in the learning MFE is slightly different than the list in the LMS.
I think what is important is that a learner can upgrade from any of the audit modes, right? We'd only want to shower learners than can upgrade the trial. I'm not entirely sure what that exact list is. We may need to figure that 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.
See my inline comments
learning_assistant/api.py
Outdated
@@ -224,3 +229,26 @@ def get_message_history(courserun_key, user, message_count): | |||
message_history = list(LearningAssistantMessage.objects.filter( | |||
course_id=courserun_key, user=user).order_by('-created')[:message_count])[::-1] | |||
return message_history | |||
|
|||
|
|||
def check_if_audit_trial_is_expired(user, upgrade_deadline): |
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.
#NIT the function name is verbose. What about audit_trial_is_expired
?
learning_assistant/api.py
Outdated
|
||
# If the user's trial is past its expiry date, return "True" for expired. Else, return False | ||
DAYS_SINCE_TRIAL_START_DATE = datetime.now() - audit_trial.start_date | ||
if DAYS_SINCE_TRIAL_START_DATE >= timedelta(days=AUDIT_TRIAL_MAX_DAYS): |
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.
What about just do return DAYS_SINCE_TRIAL_START_DATE >= timedelta(days=AUDIT_TRIAL_MAX_DAYS)
?
learning_assistant/views.py
Outdated
status=http_status.HTTP_403_FORBIDDEN, | ||
data={'detail': 'Must be staff or have valid enrollment.'} | ||
) | ||
# TODO: Add logic to make sure upgrade deadline has not passed. |
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 TODO comment should not be needed?
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.
One question about test coverage, but this looks good!
data={'detail': 'The audit trial for this user has expired.'} | ||
) | ||
else: | ||
return self._get_next_message(request, courserun_key, course_run_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 seems like a somewhat important case to cover, could a test be added to ensure that this code is still called?
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.
👍
Ticket: https://2u-internal.atlassian.net/browse/COSMO-568
Add functionality get or create an audit trial if the user is an audit learner.
If the user’s course enrollment mode (CourseMode) is audit:
When an audit learner first sends a message in Xpert LA, we’ll need to create a LearningAssistantAuditTrial to save the start date for the audit trial