Changes what fields are displayed depending on user role (#22)
* hides fields based on user permissions * updates for requested changes
This commit is contained in:
@@ -28,6 +28,7 @@ function ExamSettings(props) {
|
||||
const [saveError, setSaveError] = useState(false);
|
||||
const [submissionInProgress, setSubmissionInProgress] = useState(false);
|
||||
const [showProctortrackEscalationEmail, setShowProctortrackEscalationEmail] = useState(false);
|
||||
const isEdxStaff = getAuthenticatedUser().administrator;
|
||||
|
||||
function onEnableProctoredExamsChange(event) {
|
||||
setEnableProctoredExams(event.target.checked);
|
||||
@@ -96,10 +97,8 @@ function ExamSettings(props) {
|
||||
const currentDate = moment(moment()).format('YYYY-MM-DD[T]hh:mm:ss[Z]');
|
||||
const isAfterCourseStart = currentDate > courseStartDate;
|
||||
|
||||
const isAdmin = getAuthenticatedUser().administrator;
|
||||
|
||||
// if the user is not an administrator and it is after the course start date, user cannot edit proctoring provider
|
||||
return !isAdmin && isAfterCourseStart;
|
||||
// if the user is not edX staff and it is after the course start date, user cannot edit proctoring provider
|
||||
return !isEdxStaff && isAfterCourseStart;
|
||||
}
|
||||
|
||||
function isDisabledOption(provider) {
|
||||
@@ -154,34 +153,38 @@ function ExamSettings(props) {
|
||||
</Form.Group>
|
||||
|
||||
{/* ALLOW OPTING OUT OF PROCTORED EXAMS */}
|
||||
<fieldset aria-describedby="allowOptingOutHelpText">
|
||||
<Form.Group controlId="formAllowingOptingOut">
|
||||
<Form.Label as="legend">Allow Opting Out of Proctored Exams</Form.Label>
|
||||
<Form.Check
|
||||
type="radio"
|
||||
id="allowOptingOutYes"
|
||||
name="allowOptingOut"
|
||||
label="Yes"
|
||||
inline
|
||||
checked={allowOptingOut}
|
||||
onChange={() => onAllowOptingOutChange(true)}
|
||||
/>
|
||||
<Form.Check
|
||||
type="radio"
|
||||
id="allowOptingOutNo"
|
||||
name="allowOptingOut"
|
||||
label="No"
|
||||
inline
|
||||
checked={!allowOptingOut}
|
||||
onChange={() => onAllowOptingOutChange(false)}
|
||||
/>
|
||||
<Form.Text id="allowOptingOutHelpText">
|
||||
If this value is "Yes", learners can choose to take proctored exams without proctoring.
|
||||
If this value is "No", all learners must take the exam with proctoring.
|
||||
This setting only applies if proctored exams are enabled for the course.
|
||||
</Form.Text>
|
||||
</Form.Group>
|
||||
</fieldset>
|
||||
{ isEdxStaff && (
|
||||
<fieldset aria-describedby="allowOptingOutHelpText">
|
||||
<Form.Group controlId="formAllowingOptingOut">
|
||||
<Form.Label as="legend">Allow Opting Out of Proctored Exams</Form.Label>
|
||||
<Form.Check
|
||||
type="radio"
|
||||
id="allowOptingOutYes"
|
||||
name="allowOptingOut"
|
||||
label="Yes"
|
||||
inline
|
||||
checked={allowOptingOut}
|
||||
onChange={() => onAllowOptingOutChange(true)}
|
||||
data-test-id="allowOptingOutYes"
|
||||
/>
|
||||
<Form.Check
|
||||
type="radio"
|
||||
id="allowOptingOutNo"
|
||||
name="allowOptingOut"
|
||||
label="No"
|
||||
inline
|
||||
checked={!allowOptingOut}
|
||||
onChange={() => onAllowOptingOutChange(false)}
|
||||
data-test-id="allowOptingOutNo"
|
||||
/>
|
||||
<Form.Text id="allowOptingOutHelpText">
|
||||
If this value is "Yes", learners can choose to take proctored exams without proctoring.
|
||||
If this value is "No", all learners must take the exam with proctoring.
|
||||
This setting only applies if proctored exams are enabled for the course.
|
||||
</Form.Text>
|
||||
</Form.Group>
|
||||
</fieldset>
|
||||
)}
|
||||
|
||||
{/* PROCTORING PROVIDER */}
|
||||
<Form.Group controlId="formProctoringProvider">
|
||||
@@ -217,34 +220,37 @@ function ExamSettings(props) {
|
||||
)}
|
||||
|
||||
{/* CREATE ZENDESK TICKETS */}
|
||||
<fieldset aria-describedby="allowOptingOutHelpText">
|
||||
<Form.Group controlId="formCreateZendeskTickets">
|
||||
<Form.Label as="legend">Create Zendesk Tickets for Suspicious Proctored Exam Attempts</Form.Label>
|
||||
<Form.Check
|
||||
type="radio"
|
||||
id="createZendeskTicketsYes"
|
||||
label="Yes"
|
||||
inline
|
||||
name="createZendeskTickets"
|
||||
checked={createZendeskTickets}
|
||||
onChange={() => onCreateZendeskTicketsChange(true)}
|
||||
data-test-id="createZendeskTicketsYes"
|
||||
/>
|
||||
<Form.Check
|
||||
type="radio"
|
||||
id="createZendeskTicketsNo"
|
||||
label="No"
|
||||
inline
|
||||
name="createZendeskTickets"
|
||||
checked={!createZendeskTickets}
|
||||
onChange={() => onCreateZendeskTicketsChange(false)}
|
||||
data-test-id="createZendeskTicketsNo"
|
||||
/>
|
||||
<Form.Text id="createZendeskTicketsText">
|
||||
If this value is "Yes", a Zendesk ticket will be created for suspicious proctored exam attempts.
|
||||
</Form.Text>
|
||||
</Form.Group>
|
||||
</fieldset>
|
||||
{ isEdxStaff && (
|
||||
<fieldset aria-describedby="createZendeskTicketsText">
|
||||
<Form.Group controlId="formCreateZendeskTickets">
|
||||
<Form.Label as="legend">Create Zendesk Tickets for Suspicious Proctored Exam Attempts</Form.Label>
|
||||
<Form.Check
|
||||
type="radio"
|
||||
id="createZendeskTicketsYes"
|
||||
label="Yes"
|
||||
inline
|
||||
name="createZendeskTickets"
|
||||
checked={createZendeskTickets}
|
||||
onChange={() => onCreateZendeskTicketsChange(true)}
|
||||
data-test-id="createZendeskTicketsYes"
|
||||
/>
|
||||
<Form.Check
|
||||
type="radio"
|
||||
id="createZendeskTicketsNo"
|
||||
label="No"
|
||||
inline
|
||||
name="createZendeskTickets"
|
||||
checked={!createZendeskTickets}
|
||||
onChange={() => onCreateZendeskTicketsChange(false)}
|
||||
data-test-id="createZendeskTicketsNo"
|
||||
/>
|
||||
<Form.Text id="createZendeskTicketsText">
|
||||
If this value is "Yes",
|
||||
a Zendesk ticket will be created for suspicious proctored exam attempts.
|
||||
</Form.Text>
|
||||
</Form.Group>
|
||||
</fieldset>
|
||||
)}
|
||||
<Button
|
||||
className="btn-primary mb-3"
|
||||
data-test-id="submissionButton"
|
||||
|
||||
@@ -29,7 +29,7 @@ describe('ProctoredExamSettings check default on create zendesk ticket field tes
|
||||
}),
|
||||
}));
|
||||
|
||||
auth.getAuthenticatedUser = jest.fn(() => ({ userId: 3, administrator: false }));
|
||||
auth.getAuthenticatedUser = jest.fn(() => ({ userId: 3, administrator: true }));
|
||||
await act(async () => render(<ProctoredExamSettings {...defaultProps} />));
|
||||
});
|
||||
|
||||
@@ -251,6 +251,49 @@ describe('Disables proctoring provider options', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('Hides fields based on user permissions', () => {
|
||||
beforeEach(async () => {
|
||||
auth.getAuthenticatedHttpClient = jest.fn(() => ({
|
||||
get: async () => ({
|
||||
data: {
|
||||
proctored_exam_settings: {
|
||||
enable_proctored_exams: true,
|
||||
allow_proctoring_opt_out: false,
|
||||
proctoring_provider: 'mockproc',
|
||||
proctoring_escalation_email: 'test@example.com',
|
||||
create_zendesk_tickets: true,
|
||||
},
|
||||
available_proctoring_providers: ['software_secure', 'proctortrack', 'mockproc'],
|
||||
course_start_date: '2070-01-01T00:00:00Z',
|
||||
},
|
||||
catch: () => {},
|
||||
}),
|
||||
}));
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
cleanup();
|
||||
});
|
||||
|
||||
function mockAuthentication(isAdmin) {
|
||||
auth.getAuthenticatedUser = jest.fn(() => ({ userId: 3, administrator: isAdmin }));
|
||||
}
|
||||
|
||||
it('hides opting out and zendesk tickets for non edX staff', async () => {
|
||||
mockAuthentication(false);
|
||||
await act(async () => render(<ProctoredExamSettings {...defaultProps} />));
|
||||
expect(screen.queryByTestId('allowOptingOutYes')).toBeNull();
|
||||
expect(screen.queryByTestId('createZendeskTicketsYes')).toBeNull();
|
||||
});
|
||||
|
||||
it('shows opting out and zendesk tickets for edX staff', async () => {
|
||||
mockAuthentication(true);
|
||||
await act(async () => render(<ProctoredExamSettings {...defaultProps} />));
|
||||
expect(screen.queryByTestId('allowOptingOutYes')).not.toBeNull();
|
||||
expect(screen.queryByTestId('createZendeskTicketsYes')).not.toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('ProctoredExamSettings connection states tests', () => {
|
||||
it('shows the spinner before the connection is complete', async () => {
|
||||
render(<ProctoredExamSettings {...defaultProps} />);
|
||||
|
||||
Reference in New Issue
Block a user