From 1d401bbbdec1687d05f6478e8b97dc7a0ea85be0 Mon Sep 17 00:00:00 2001 From: Ishan Masdekar Date: Fri, 2 Aug 2024 12:27:39 +0530 Subject: [PATCH] fix: corrects the navigation issue if the student does not pass the entrance exam - adds checks while rendering the next button text for status of the entrance exam. closes #1415 Signed-off by: Ishan Masdekar --- .../certificate-status/CertificateStatus.jsx | 7 +++++++ src/courseware/course/course-exit/utils.js | 16 +++++++++++++++- .../course/sequence/sequence-navigation/hooks.js | 11 +++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/course-home/progress-tab/certificate-status/CertificateStatus.jsx b/src/course-home/progress-tab/certificate-status/CertificateStatus.jsx index cc73ca0690..03837ee1c9 100644 --- a/src/course-home/progress-tab/certificate-status/CertificateStatus.jsx +++ b/src/course-home/progress-tab/certificate-status/CertificateStatus.jsx @@ -19,6 +19,10 @@ const CertificateStatus = ({ intl }) => { courseId, } = useSelector(state => state.courseHome); + const { + entranceExamData, + } = useModel('coursewareMeta', courseId); + const { isEnrolled, org, @@ -42,6 +46,8 @@ const CertificateStatus = ({ intl }) => { certificateAvailableDate, } = certificateData || {}; + const entranceExamPassed = entranceExamData?.entranceExamPassed ?? null; + const mode = getCourseExitMode( certificateData, hasScheduledContent, @@ -49,6 +55,7 @@ const CertificateStatus = ({ intl }) => { userHasPassingGrade, null, // CourseExitPageIsActive canViewCertificate, + entranceExamPassed, ); const eventProperties = { diff --git a/src/courseware/course/course-exit/utils.js b/src/courseware/course/course-exit/utils.js index da1d353094..c896b77e29 100644 --- a/src/courseware/course/course-exit/utils.js +++ b/src/courseware/course/course-exit/utils.js @@ -9,6 +9,7 @@ const COURSE_EXIT_MODES = { celebration: 1, nonPassing: 2, inProgress: 3, + entranceExamFail: 4, }; // These are taken from the edx-platform `get_cert_data` function found in lms/courseware/views/views.py @@ -32,9 +33,14 @@ function getCourseExitMode( userHasPassingGrade, courseExitPageIsActive = null, canImmediatelyViewCertificate = false, + entranceExamPassed = null, ) { const authenticatedUser = getAuthenticatedUser(); + if (entranceExamPassed === false) { + return COURSE_EXIT_MODES.entranceExamFail; + } + if (courseExitPageIsActive === false || !authenticatedUser || !isEnrolled) { return COURSE_EXIT_MODES.disabled; } @@ -73,6 +79,7 @@ function GetCourseExitNavigation(courseId, intl) { isEnrolled, userHasPassingGrade, courseExitPageIsActive, + entranceExamData: { entranceExamPassed }, } = useModel('coursewareMeta', courseId); const { canViewCertificate } = useModel('courseHomeMeta', courseId); const exitMode = getCourseExitMode( @@ -82,8 +89,15 @@ function GetCourseExitNavigation(courseId, intl) { userHasPassingGrade, courseExitPageIsActive, canViewCertificate, + entranceExamPassed, ); - const exitActive = exitMode !== COURSE_EXIT_MODES.disabled; + + // exitActive is used to enable/disable the exit i.e. next buttons. + // COURSE_EXIT_MODES denote the current status of the course. + // Available COURSE_EXIT_MODES: disabled, celebration, nonPassing, inProgress, entranceExamFail + // If the user fails the entrance exam, + // access to further course sections should not be allowed i.e. disable the next buttons. + const exitActive = ((exitMode !== COURSE_EXIT_MODES.disabled) && (exitMode !== COURSE_EXIT_MODES.entranceExamFail)); let exitText; switch (exitMode) { diff --git a/src/courseware/course/sequence/sequence-navigation/hooks.js b/src/courseware/course/sequence/sequence-navigation/hooks.js index ef0db2035b..d0195468c8 100644 --- a/src/courseware/course/sequence/sequence-navigation/hooks.js +++ b/src/courseware/course/sequence/sequence-navigation/hooks.js @@ -13,6 +13,7 @@ export function useSequenceNavigationMetadata(currentSequenceId, currentUnitId) const sequence = useModel('sequences', currentSequenceId); const courseId = useSelector(state => state.courseware.courseId); const courseStatus = useSelector(state => state.courseware.courseStatus); + const { entranceExamData: { entranceExamPassed } } = useModel('coursewareMeta', courseId); const sequenceStatus = useSelector(state => state.courseware.sequenceStatus); // If we don't know the sequence and unit yet, then assume no. @@ -25,6 +26,16 @@ export function useSequenceNavigationMetadata(currentSequenceId, currentUnitId) }; } + // if entrance exam is not passed then we should treat this as 1st and last unit + if (entranceExamPassed === false) { + return { + isFirstUnit: true, + isLastUnit: true, + navigationDisabledNextSequence: false, + navigationDisabledPrevSequence: false, + }; + } + const sequenceIndex = sequenceIds.indexOf(currentSequenceId); const unitIndex = sequence.unitIds.indexOf(currentUnitId);