From 8457727a0a2b33614c380497ad0fb0cd02b664a4 Mon Sep 17 00:00:00 2001 From: Michael Roytman Date: Wed, 20 Dec 2023 12:44:36 -0500 Subject: [PATCH] feat: add support for a technical support URL in the LTI-based provider download instructions (#127) This commit adds support for displaying a technical support URL for LTI-based providers on the download instructions interstitial. The download instructions will display a technical support URL when it is returned from the proctoring settings backend endpoint. If the technical support URL is not available, then the technical support email and technical support phone number will be used instead. --- src/data/__snapshots__/redux.test.jsx.snap | 5 ++ src/data/slice.js | 1 + src/instructions/Instructions.test.jsx | 42 ++++++++++++- .../LtiProviderInstructions.jsx | 63 +++++++++++++------ .../download-instructions/index.jsx | 2 + 5 files changed, 92 insertions(+), 21 deletions(-) diff --git a/src/data/__snapshots__/redux.test.jsx.snap b/src/data/__snapshots__/redux.test.jsx.snap index e1cb7ba9..69475b13 100644 --- a/src/data/__snapshots__/redux.test.jsx.snap +++ b/src/data/__snapshots__/redux.test.jsx.snap @@ -84,6 +84,7 @@ Object { "provider_name": "", "provider_tech_support_email": "", "provider_tech_support_phone": "", + "provider_tech_support_url": "", }, "timeIsOver": false, }, @@ -129,6 +130,7 @@ Object { "provider_name": "", "provider_tech_support_email": "", "provider_tech_support_phone": "", + "provider_tech_support_url": "", }, "timeIsOver": false, }, @@ -148,6 +150,7 @@ Object { "provider_name": "", "provider_tech_support_email": "", "provider_tech_support_phone": "", + "provider_tech_support_url": "", } `; @@ -302,6 +305,7 @@ Object { "provider_name": "", "provider_tech_support_email": "", "provider_tech_support_phone": "", + "provider_tech_support_url": "", }, "timeIsOver": false, }, @@ -370,6 +374,7 @@ Object { "provider_name": "", "provider_tech_support_email": "", "provider_tech_support_phone": "", + "provider_tech_support_url": "", }, "timeIsOver": false, }, diff --git a/src/data/slice.js b/src/data/slice.js index 39c038ed..0b633dcc 100644 --- a/src/data/slice.js +++ b/src/data/slice.js @@ -17,6 +17,7 @@ export const examSlice = createSlice({ }, provider_tech_support_email: '', provider_tech_support_phone: '', + provider_tech_support_url: '', provider_name: '', learner_notification_from_email: '', integration_specific_email: '', diff --git a/src/instructions/Instructions.test.jsx b/src/instructions/Instructions.test.jsx index 92458074..22cbba99 100644 --- a/src/instructions/Instructions.test.jsx +++ b/src/instructions/Instructions.test.jsx @@ -723,7 +723,7 @@ describe('SequenceExamWrapper', () => { expect(screen.getByText('You have submitted this proctored exam for review')).toBeInTheDocument(); }); - it('Shows correct download instructions for LTI provider if attempt status is created', () => { + it('Shows correct download instructions for LTI provider if attempt status is created, with support email and phone', () => { store.getState = () => ({ examState: Factory.build('examState', { activeAttempt: {}, @@ -760,6 +760,46 @@ describe('SequenceExamWrapper', () => { expect(screen.getByText('Start Exam')).toBeInTheDocument(); }); + it('Shows correct download instructions for LTI provider if attempt status is created with support URL', () => { + store.getState = () => ({ + examState: Factory.build('examState', { + activeAttempt: {}, + proctoringSettings: Factory.build('proctoringSettings', { + provider_name: 'LTI Provider', + provider_tech_support_email: 'ltiprovidersupport@example.com', + provider_tech_support_phone: '+123456789', + provider_tech_support_url: 'www.example.com', + }), + exam: Factory.build('exam', { + is_proctored: true, + type: ExamType.PROCTORED, + attempt: Factory.build('attempt', { + attempt_status: ExamStatus.CREATED, + }), + }), + }), + }); + + render( + + +
Sequence
+
+
, + { store }, + ); + + expect(screen.getByText( + 'If you have issues relating to proctoring, you can contact LTI Provider technical support by visiting', + { exact: false }, + )).toBeInTheDocument(); + expect(screen.getByRole('link', { name: 'www.example.com in a new tab' })).toHaveAttribute('href', 'www.example.com'); + + expect(screen.getByText('Set up and start your proctored exam.')).toBeInTheDocument(); + expect(screen.getByText('Start System Check')).toBeInTheDocument(); + expect(screen.getByText('Start Exam')).toBeInTheDocument(); + }); + it('Hides support contact info on download instructions for LTI provider if not provided', () => { store.getState = () => ({ examState: Factory.build('examState', { diff --git a/src/instructions/proctored_exam/download-instructions/LtiProviderInstructions.jsx b/src/instructions/proctored_exam/download-instructions/LtiProviderInstructions.jsx index e9cc2d84..a68e9fca 100644 --- a/src/instructions/proctored_exam/download-instructions/LtiProviderInstructions.jsx +++ b/src/instructions/proctored_exam/download-instructions/LtiProviderInstructions.jsx @@ -1,47 +1,70 @@ import React from 'react'; import PropTypes from 'prop-types'; import { FormattedMessage } from '@edx/frontend-platform/i18n'; +import { Hyperlink } from '@edx/paragon'; const LtiProviderExamInstructions = ({ - providerName, supportEmail, supportPhone, -}) => ( - <> -

- -

- {supportEmail && supportPhone && ( -

+ providerName, supportEmail, supportPhone, supportURL, +}) => { + const supportURLHyperlink = (chunks) => ( + + {chunks} + + ); + + const getSupportText = () => { + // We assume that an LTI-based provider will either have a supportURL or a supportEmail and supportPhone. + // In the unlikely event a provider has all three, we prioritize the supportURL. + if (supportURL) { + return ( {supportURL}.'} + values={{ + providerName, + supportURL, + a: supportURLHyperlink, + }} + /> + ); + } + if (supportEmail && supportPhone) { + return ( + -

- )} - -); + ); + } + return null; + }; + + return ( +

+ {getSupportText()} +

+ ); +}; LtiProviderExamInstructions.propTypes = { providerName: PropTypes.string, supportEmail: PropTypes.string, supportPhone: PropTypes.string, + supportURL: PropTypes.string, }; LtiProviderExamInstructions.defaultProps = { providerName: '', supportEmail: '', supportPhone: '', + supportURL: '', }; export default LtiProviderExamInstructions; diff --git a/src/instructions/proctored_exam/download-instructions/index.jsx b/src/instructions/proctored_exam/download-instructions/index.jsx index 868db55b..298d81c2 100644 --- a/src/instructions/proctored_exam/download-instructions/index.jsx +++ b/src/instructions/proctored_exam/download-instructions/index.jsx @@ -39,6 +39,7 @@ const DownloadSoftwareProctoredExamInstructions = ({ intl, skipProctoredExam }) provider_name: providerName, provider_tech_support_email: supportEmail, provider_tech_support_phone: supportPhone, + provider_tech_support_url: supportURL, exam_proctoring_backend: proctoringBackend, } = proctoringSettings; const examHasLtiProvider = !useLegacyAttemptApi; @@ -81,6 +82,7 @@ const DownloadSoftwareProctoredExamInstructions = ({ intl, skipProctoredExam }) providerName={providerName} supportEmail={supportEmail} supportPhone={supportPhone} + supportURL={supportURL} /> ); }