diff --git a/.env b/.env index a2631350..d3a151bb 100644 --- a/.env +++ b/.env @@ -1,3 +1,6 @@ NODE_ENV='production' LANGUAGE_PREFERENCE_COOKIE_NAME=null LMS_BASE_URL=null +CONTACT_URL='' +PROCTORED_EXAM_FAQ_URL='' +PROCTORED_EXAM_RULES_URL='' diff --git a/.env.development b/.env.development index cbffc792..45591fe0 100644 --- a/.env.development +++ b/.env.development @@ -1,3 +1,6 @@ NODE_ENV='development' LANGUAGE_PREFERENCE_COOKIE_NAME='openedx-language-preference' LMS_BASE_URL='http://localhost:18000' +CONTACT_URL='http://localhost:18000/contact' +PROCTORED_EXAM_FAQ_URL='' +PROCTORED_EXAM_RULES_URL='' diff --git a/.env.test b/.env.test index b9a422f7..29f4ab3d 100644 --- a/.env.test +++ b/.env.test @@ -1,3 +1,6 @@ LANGUAGE_PREFERENCE_COOKIE_NAME='openedx-language-preference' LMS_BASE_URL='http://localhost:18000' EXAMS_BASE_URL='http://localhost:18740' +CONTACT_URL='http://localhost:18000/contact' +PROCTORED_EXAM_FAQ_URL='' +PROCTORED_EXAM_RULES_URL='' diff --git a/codecov.yml b/codecov.yml index c41479ba..ec8193be 100644 --- a/codecov.yml +++ b/codecov.yml @@ -3,7 +3,7 @@ coverage: project: default: target: auto - threshold: 0% + threshold: 0.2% patch: default: target: auto diff --git a/src/data/__factories__/proctoringSettings.factory.js b/src/data/__factories__/proctoringSettings.factory.js index 0bd59865..3ebf65c5 100644 --- a/src/data/__factories__/proctoringSettings.factory.js +++ b/src/data/__factories__/proctoringSettings.factory.js @@ -2,14 +2,6 @@ import { Factory } from 'rosie'; // eslint-disable-line import/no-extraneous-dep Factory.define('proctoringSettings') .attrs({ - platform_name: 'Your Platform Name Here', - contact_us: 'info@example.com', - link_urls: { - contact_us: 'https://example.com/contact_us/', - faq: 'https://example.com/faq/', - online_proctoring_rules: 'https://example.com/online_proctoring_rules/', - tech_requirements: 'https://example.com/tech_requirements/', - }, exam_proctoring_backend: { download_url: '', instructions: [], diff --git a/src/data/__snapshots__/redux.test.jsx.snap b/src/data/__snapshots__/redux.test.jsx.snap index 8157c9dd..8906e7f6 100644 --- a/src/data/__snapshots__/redux.test.jsx.snap +++ b/src/data/__snapshots__/redux.test.jsx.snap @@ -75,7 +75,6 @@ Object { }, "isLoading": false, "proctoringSettings": Object { - "contact_us": "", "exam_proctoring_backend": Object { "download_url": "", "instructions": Array [], @@ -84,8 +83,6 @@ Object { }, "integration_specific_email": "", "learner_notification_from_email": "", - "link_urls": null, - "platform_name": "", "provider_name": "", "provider_tech_support_email": "", "provider_tech_support_phone": "", @@ -124,7 +121,6 @@ Object { }, "isLoading": false, "proctoringSettings": Object { - "contact_us": "", "exam_proctoring_backend": Object { "download_url": "", "instructions": Array [], @@ -133,8 +129,6 @@ Object { }, "integration_specific_email": "", "learner_notification_from_email": "", - "link_urls": null, - "platform_name": "", "provider_name": "", "provider_tech_support_email": "", "provider_tech_support_phone": "", @@ -212,7 +206,6 @@ Object { }, "isLoading": false, "proctoringSettings": Object { - "contact_us": "", "exam_proctoring_backend": Object { "download_url": "", "instructions": Array [], @@ -221,8 +214,6 @@ Object { }, "integration_specific_email": "", "learner_notification_from_email": "", - "link_urls": null, - "platform_name": "", "provider_name": "", "provider_tech_support_email": "", "provider_tech_support_phone": "", @@ -261,7 +252,6 @@ Object { }, "isLoading": false, "proctoringSettings": Object { - "contact_us": "", "exam_proctoring_backend": Object { "download_url": "", "instructions": Array [], @@ -270,8 +260,6 @@ Object { }, "integration_specific_email": "", "learner_notification_from_email": "", - "link_urls": null, - "platform_name": "", "provider_name": "", "provider_tech_support_email": "", "provider_tech_support_phone": "", @@ -283,7 +271,6 @@ Object { exports[`Data layer integration tests Test getProctoringSettings Should fail to fetch if error occurs 1`] = ` Object { - "contact_us": "", "exam_proctoring_backend": Object { "download_url": "", "instructions": Array [], @@ -292,8 +279,6 @@ Object { }, "integration_specific_email": "", "learner_notification_from_email": "", - "link_urls": null, - "platform_name": "", "provider_name": "", "provider_tech_support_email": "", "provider_tech_support_phone": "", @@ -302,7 +287,6 @@ Object { exports[`Data layer integration tests Test getProctoringSettings Should get, and save proctoringSettings 1`] = ` Object { - "contact_us": "info@example.com", "exam_proctoring_backend": Object { "download_url": "", "instructions": Array [], @@ -311,13 +295,6 @@ Object { }, "integration_specific_email": "", "learner_notification_from_email": "", - "link_urls": Object { - "contact_us": "https://example.com/contact_us/", - "faq": "https://example.com/faq/", - "online_proctoring_rules": "https://example.com/online_proctoring_rules/", - "tech_requirements": "https://example.com/tech_requirements/", - }, - "platform_name": "Your Platform Name Here", "provider_name": "", "provider_tech_support_email": "", "provider_tech_support_phone": "", @@ -416,7 +393,6 @@ Object { }, "isLoading": false, "proctoringSettings": Object { - "contact_us": "", "exam_proctoring_backend": Object { "download_url": "", "instructions": Array [], @@ -425,8 +401,6 @@ Object { }, "integration_specific_email": "", "learner_notification_from_email": "", - "link_urls": null, - "platform_name": "", "provider_name": "", "provider_tech_support_email": "", "provider_tech_support_phone": "", diff --git a/src/data/slice.js b/src/data/slice.js index b573b734..6af6c667 100644 --- a/src/data/slice.js +++ b/src/data/slice.js @@ -9,9 +9,6 @@ export const examSlice = createSlice({ activeAttempt: null, // has the same structure as attempt in exam object allowProctoringOptOut: false, proctoringSettings: { - platform_name: '', - contact_us: '', - link_urls: null, exam_proctoring_backend: { download_url: '', instructions: [], diff --git a/src/exam/Exam.jsx b/src/exam/Exam.jsx index 1dba1f29..eeb4de42 100644 --- a/src/exam/Exam.jsx +++ b/src/exam/Exam.jsx @@ -57,10 +57,12 @@ const Exam = ({ const proctoredExamTypes = [ExamType.ONBOARDING, ExamType.PRACTICE, ExamType.PROCTORED]; useEffect(() => { - if (examId) { - getProctoringSettings(); - } if (proctoredExamTypes.includes(examType)) { + // only fetch proctoring settings for a proctored exam + if (examId) { + getProctoringSettings(); + } + // Only exclude Timed Exam when restricting access to exams setHasProctoredExamAccess(canAccessProctoredExams); } diff --git a/src/instructions/Instructions.test.jsx b/src/instructions/Instructions.test.jsx index 8bfedf55..6e424879 100644 --- a/src/instructions/Instructions.test.jsx +++ b/src/instructions/Instructions.test.jsx @@ -137,9 +137,6 @@ describe('SequenceExamWrapper', () => { examState: Factory.build('examState', { timeIsOver: true, allowProctoringOptOut: true, - proctoringSettings: Factory.build('proctoringSettings', { - platform_name: 'Your Platform', - }), exam: Factory.build('exam', { is_proctored: true, attempt: {}, @@ -178,9 +175,6 @@ describe('SequenceExamWrapper', () => { store.getState = () => ({ examState: Factory.build('examState', { timeIsOver: true, - proctoringSettings: Factory.build('proctoringSettings', { - platform_name: 'Your Platform', - }), exam: Factory.build('exam', { is_proctored: true, type: ExamType.PROCTORED, @@ -214,13 +208,6 @@ describe('SequenceExamWrapper', () => { store.getState = () => ({ examState: Factory.build('examState', { timeIsOver: true, - proctoringSettings: Factory.build('proctoringSettings', { - link_urls: [ - { - contact_us: 'http://localhost:2000', - }, - ], - }), exam: Factory.build('exam', { type: ExamType.PROCTORED, attempt: Factory.build('attempt', { @@ -245,9 +232,6 @@ describe('SequenceExamWrapper', () => { store.getState = () => ({ examState: Factory.build('examState', { timeIsOver: true, - proctoringSettings: Factory.build('proctoringSettings', { - platform_name: 'Platform Name', - }), exam: Factory.build('exam', { type: ExamType.PROCTORED, attempt: Factory.build('attempt', { @@ -359,7 +343,6 @@ describe('SequenceExamWrapper', () => { store.getState = () => ({ examState: Factory.build('examState', { proctoringSettings: Factory.build('proctoringSettings', { - platform_name: 'Your Platform', integration_specific_email: integrationEmail, }), exam: Factory.build('exam', { @@ -394,9 +377,6 @@ describe('SequenceExamWrapper', () => { it('Shows submit onboarding exam instructions if exam is onboarding and attempt status is ready_to_submit', () => { store.getState = () => ({ examState: Factory.build('examState', { - proctoringSettings: Factory.build('proctoringSettings', { - platform_name: 'Your Platform', - }), activeAttempt: {}, exam: Factory.build('exam', { is_proctored: true, @@ -423,9 +403,6 @@ describe('SequenceExamWrapper', () => { it('Shows error onboarding exam instructions if exam is onboarding and attempt status is error', () => { store.getState = () => ({ examState: Factory.build('examState', { - proctoringSettings: Factory.build('proctoringSettings', { - platform_name: 'Your Platform', - }), activeAttempt: {}, exam: Factory.build('exam', { is_proctored: true, @@ -454,7 +431,6 @@ describe('SequenceExamWrapper', () => { store.getState = () => ({ examState: Factory.build('examState', { proctoringSettings: Factory.build('proctoringSettings', { - platform_name: 'Your Platform', integration_specific_email: 'test@example.com', learner_notification_from_email: 'test_notification@example.com', }), @@ -493,7 +469,6 @@ describe('SequenceExamWrapper', () => { store.getState = () => ({ examState: Factory.build('examState', { proctoringSettings: Factory.build('proctoringSettings', { - platform_name: 'Your Platform', integration_specific_email: 'test@example.com', }), activeAttempt: {}, @@ -523,9 +498,6 @@ describe('SequenceExamWrapper', () => { it('Shows error practice exam instructions if exam is onboarding and attempt status is error', () => { store.getState = () => ({ examState: Factory.build('examState', { - proctoringSettings: Factory.build('proctoringSettings', { - platform_name: 'Your Platform', - }), activeAttempt: {}, exam: Factory.build('exam', { is_proctored: true, @@ -553,9 +525,6 @@ describe('SequenceExamWrapper', () => { it('Shows submitted practice exam instructions if exam is onboarding and attempt status is submitted', () => { store.getState = () => ({ examState: Factory.build('examState', { - proctoringSettings: Factory.build('proctoringSettings', { - platform_name: 'Your Platform', - }), activeAttempt: {}, exam: Factory.build('exam', { is_proctored: true, @@ -583,9 +552,6 @@ describe('SequenceExamWrapper', () => { it('Does not show expired page if exam is passed due date and is practice', () => { store.getState = () => ({ examState: Factory.build('examState', { - proctoringSettings: Factory.build('proctoringSettings', { - platform_name: 'Your Platform', - }), activeAttempt: {}, exam: Factory.build('exam', { is_proctored: true, @@ -610,9 +576,6 @@ describe('SequenceExamWrapper', () => { it.each([ExamType.TIMED, ExamType.PROCTORED, ExamType.ONBOARDING])('Shows expired page when exam is passed due date and is %s', (examType) => { store.getState = () => ({ examState: Factory.build('examState', { - proctoringSettings: Factory.build('proctoringSettings', { - platform_name: 'Your Platform', - }), activeAttempt: {}, exam: Factory.build('exam', { is_proctored: true, @@ -640,9 +603,6 @@ describe('SequenceExamWrapper', () => { (item) => { store.getState = () => ({ examState: Factory.build('examState', { - proctoringSettings: Factory.build('proctoringSettings', { - platform_name: 'Your Platform', - }), activeAttempt: {}, exam: Factory.build('exam', { is_proctored: true, @@ -672,9 +632,6 @@ describe('SequenceExamWrapper', () => { it('Shows exam content for timed exam if attempt status is submitted, due date has passed and hide after due is set to false', () => { store.getState = () => ({ examState: Factory.build('examState', { - proctoringSettings: Factory.build('proctoringSettings', { - platform_name: 'Your Platform', - }), activeAttempt: {}, exam: Factory.build('exam', { type: ExamType.TIMED, @@ -702,9 +659,6 @@ describe('SequenceExamWrapper', () => { it('Shows submitted exam page for proctored exams if attempt status is submitted, due date has passed and hide after due is set to false', () => { store.getState = () => ({ examState: Factory.build('examState', { - proctoringSettings: Factory.build('proctoringSettings', { - platform_name: 'Your Platform', - }), activeAttempt: {}, exam: Factory.build('exam', { type: ExamType.PROCTORED, @@ -732,9 +686,6 @@ describe('SequenceExamWrapper', () => { it('Shows submitted page when proctored exam is in second_review_required status', () => { store.getState = () => ({ examState: Factory.build('examState', { - proctoringSettings: Factory.build('proctoringSettings', { - platform_name: 'Your Platform', - }), activeAttempt: {}, exam: Factory.build('exam', { is_proctored: true, @@ -807,9 +758,6 @@ describe('SequenceExamWrapper', () => { it('Shows error message if receives unknown attempt status', () => { store.getState = () => ({ examState: Factory.build('examState', { - proctoringSettings: Factory.build('proctoringSettings', { - platform_name: 'Your Platform', - }), activeAttempt: {}, exam: Factory.build('exam', { type: ExamType.TIMED, @@ -835,9 +783,6 @@ describe('SequenceExamWrapper', () => { it('Shows ready to start page when proctored exam is in ready_to_start status', () => { store.getState = () => ({ examState: Factory.build('examState', { - proctoringSettings: Factory.build('proctoringSettings', { - platform_name: 'Your Platform', - }), activeAttempt: {}, exam: Factory.build('exam', { is_proctored: true, @@ -864,9 +809,6 @@ describe('SequenceExamWrapper', () => { it('Shows loading spinner while waiting to start exam', () => { store.getState = () => ({ examState: Factory.build('examState', { - proctoringSettings: Factory.build('proctoringSettings', { - platform_name: 'Your Platform', - }), activeAttempt: {}, exam: Factory.build('exam', { is_proctored: true, diff --git a/src/instructions/proctored_exam/ErrorProctoredExamInstructions.jsx b/src/instructions/proctored_exam/ErrorProctoredExamInstructions.jsx index a108f073..e0acde76 100644 --- a/src/instructions/proctored_exam/ErrorProctoredExamInstructions.jsx +++ b/src/instructions/proctored_exam/ErrorProctoredExamInstructions.jsx @@ -1,16 +1,16 @@ import React, { useContext } from 'react'; import { FormattedMessage } from '@edx/frontend-platform/i18n'; +import { getConfig } from '@edx/frontend-platform'; import { Hyperlink, MailtoLink } from '@edx/paragon'; import ExamStateContext from '../../context'; const ErrorProctoredExamInstructions = () => { const state = useContext(ExamStateContext); const { - link_urls: linkUrls, - platform_name: platformName, proctoring_escalation_email: proctoringEscalationEmail, } = state.proctoringSettings || {}; - const contactUsUrl = linkUrls && linkUrls.contact_us; + const platformName = getConfig().SITE_NAME; + const contactUsUrl = getConfig().CONTACT_URL; const renderBody = () => { if (proctoringEscalationEmail) { diff --git a/src/instructions/proctored_exam/Footer.jsx b/src/instructions/proctored_exam/Footer.jsx index 683f411d..3a6194af 100644 --- a/src/instructions/proctored_exam/Footer.jsx +++ b/src/instructions/proctored_exam/Footer.jsx @@ -1,13 +1,10 @@ -import React, { useContext } from 'react'; +import React from 'react'; import { Button } from '@edx/paragon'; import { FormattedMessage } from '@edx/frontend-platform/i18n'; -import ExamStateContext from '../../context'; +import { getConfig } from '@edx/frontend-platform'; const Footer = () => { - const state = useContext(ExamStateContext); - const { proctoringSettings } = state; - const { link_urls: linkUrls } = proctoringSettings; - const faqUrl = linkUrls && linkUrls.faq; + const faqUrl = getConfig().PROCTORED_EXAM_FAQ_URL; return (
diff --git a/src/instructions/proctored_exam/ReadyToStartProctoredExamInstructions.jsx b/src/instructions/proctored_exam/ReadyToStartProctoredExamInstructions.jsx index 60de1307..5c180220 100644 --- a/src/instructions/proctored_exam/ReadyToStartProctoredExamInstructions.jsx +++ b/src/instructions/proctored_exam/ReadyToStartProctoredExamInstructions.jsx @@ -1,5 +1,6 @@ import React, { useContext, useEffect, useState } from 'react'; import { FormattedMessage } from '@edx/frontend-platform/i18n'; +import { getConfig } from '@edx/frontend-platform'; import { Button, Container, Spinner } from '@edx/paragon'; import ExamStateContext from '../../context'; import Footer from './Footer'; @@ -8,14 +9,13 @@ const ReadyToStartProctoredExamInstructions = () => { const state = useContext(ExamStateContext); const { exam, - proctoringSettings, getExamReviewPolicy, startProctoredExam, } = state; const { attempt, reviewPolicy } = exam; const { total_time: examDuration } = attempt; - const { link_urls: linkUrls, platform_name: platformName } = proctoringSettings; - const rulesUrl = linkUrls && linkUrls.online_proctoring_rules; + const platformName = getConfig().SITE_NAME; + const rulesUrl = getConfig().PROCTORED_EXAM_RULES_URL; const [beginExamClicked, setBeginExamClicked] = useState(false); useEffect(() => { diff --git a/src/instructions/proctored_exam/RejectedProctoredExamInstructions.jsx b/src/instructions/proctored_exam/RejectedProctoredExamInstructions.jsx index 7f1ebc2c..8f703c90 100644 --- a/src/instructions/proctored_exam/RejectedProctoredExamInstructions.jsx +++ b/src/instructions/proctored_exam/RejectedProctoredExamInstructions.jsx @@ -1,11 +1,9 @@ -import React, { useContext } from 'react'; +import React from 'react'; import { FormattedMessage } from '@edx/frontend-platform/i18n'; -import ExamStateContext from '../../context'; +import { getConfig } from '@edx/frontend-platform'; const RejectedProctoredExamInstructions = () => { - const state = useContext(ExamStateContext); - const { proctoringSettings } = state; - const { platform_name: platformName } = proctoringSettings; + const platformName = getConfig().SITE_NAME; return ( <> diff --git a/src/instructions/proctored_exam/prerequisites-instructions/Failed.jsx b/src/instructions/proctored_exam/prerequisites-instructions/Failed.jsx index 9e70ff52..eaa3f21e 100644 --- a/src/instructions/proctored_exam/prerequisites-instructions/Failed.jsx +++ b/src/instructions/proctored_exam/prerequisites-instructions/Failed.jsx @@ -1,12 +1,14 @@ import React from 'react'; import PropTypes from 'prop-types'; import { FormattedMessage } from '@edx/frontend-platform/i18n'; +import { getConfig } from '@edx/frontend-platform'; import SkipProctoredExamButton from '../SkipProctoredExamButton'; const FailedPrerequisitesProctoredExamInstructions = (props) => { const { - allowProctoringOptOut, prerequisites, platformName, skipProctoredExam, + allowProctoringOptOut, prerequisites, skipProctoredExam, } = props; + const platformName = getConfig().SITE_NAME; return ( <> @@ -56,7 +58,6 @@ const FailedPrerequisitesProctoredExamInstructions = (props) => { FailedPrerequisitesProctoredExamInstructions.propTypes = { allowProctoringOptOut: PropTypes.bool.isRequired, prerequisites: PropTypes.arrayOf(PropTypes.object).isRequired, - platformName: PropTypes.string.isRequired, skipProctoredExam: PropTypes.func.isRequired, }; diff --git a/src/instructions/proctored_exam/prerequisites-instructions/index.jsx b/src/instructions/proctored_exam/prerequisites-instructions/index.jsx index e3ebdc6d..2634678f 100644 --- a/src/instructions/proctored_exam/prerequisites-instructions/index.jsx +++ b/src/instructions/proctored_exam/prerequisites-instructions/index.jsx @@ -9,17 +9,15 @@ import Footer from '../Footer'; const PrerequisitesProctoredExamInstructions = ({ skipProctoredExam }) => { const state = useContext(ExamStateContext); - const { exam, proctoringSettings, allowProctoringOptOut } = state; + const { exam, allowProctoringOptOut } = state; const { prerequisite_status: prerequisitesData } = exam; const { pending_prerequisites: pending, failed_prerequisites: failed } = prerequisitesData; - const { platform_name: platformName } = proctoringSettings; let child = null; if (failed && failed.length > 0) { child = (