Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
be94bcd
chore: Refactor proctoring provider handling in Settings
santhosh-apphelix-2u Oct 1, 2025
6f8a9e6
Merge branch 'openedx:master' into master
santhosh-apphelix-2u Oct 6, 2025
da94636
chore: Skip Zendesk ticket tests for deprecated provider
santhosh-apphelix-2u Oct 6, 2025
fd78dd6
chore: Skip proctortrack related tests in Settings.test.jsx
santhosh-apphelix-2u Oct 6, 2025
19a279e
chore: Skip tests for Proctortrack deprecation
santhosh-apphelix-2u Oct 6, 2025
e1f198c
chore: Skip alert test for invalid proctoring escalation email
santhosh-apphelix-2u Oct 6, 2025
be50450
chore: Update test to select escalation email by display value
santhosh-apphelix-2u Oct 6, 2025
9942e16
chore: Remove deprecated Proctortrack tests from Settings.test.jsx
santhosh-apphelix-2u Oct 6, 2025
e828d95
Merge branch 'openedx:master' into master
santhosh-apphelix-2u Oct 7, 2025
60af877
feat: remove Create Zendesk Tickets for suspicious attempts setting f…
santhosh-apphelix-2u Oct 7, 2025
a7c60e0
feat: Remove create_zendesk_tickets from test settings
santhosh-apphelix-2u Oct 7, 2025
c834e8d
chore: Update proctoring provider logic in Settings.jsx
santhosh-apphelix-2u Oct 8, 2025
d656b94
chore: Update proctoring escalation email tests
santhosh-apphelix-2u Oct 8, 2025
5cd57dd
chore: Fix indentation in proctoring settings test
santhosh-apphelix-2u Oct 8, 2025
fa576c8
chore: Refactor proctoring provider handling in Settings
santhosh-apphelix-2u Oct 8, 2025
9ecc0ef
chore: Fix test case description formatting for proctoring
santhosh-apphelix-2u Oct 8, 2025
2a65c96
chore: Remove unnecessary whitespace in Settings.test.jsx
santhosh-apphelix-2u Oct 8, 2025
1af31bb
chore: Remove create_zendesk_tickets from settings test
santhosh-apphelix-2u Oct 8, 2025
31e9e7c
chore: Update proctoring settings handling
santhosh-apphelix-2u Oct 8, 2025
d9e6a4a
Merge branch 'openedx:master' into COSMO2-110-zendesk-removal
santhosh-apphelix-2u Oct 8, 2025
92b9807
chore: Enable test for escalation email field visibility
santhosh-apphelix-2u Oct 8, 2025
a1ea9dc
chore: Remove unnecessary blank line in Settings.test.jsx
santhosh-apphelix-2u Oct 8, 2025
af03a5f
feat: Remove createZendeskTickets from settings
santhosh-apphelix-2u Oct 13, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 3 additions & 30 deletions plugins/course-apps/proctoring/Settings.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ const ProctoringSettings = ({ onClose }) => {
proctoringProvider: false,
escalationEmail: '',
allowOptingOut: false,
createZendeskTickets: false,
};
const [formValues, setFormValues] = useState(initialFormValues);
const [loading, setLoading] = useState(true);
Expand Down Expand Up @@ -78,17 +77,16 @@ const ProctoringSettings = ({ onClose }) => {
const value = target.type === 'checkbox' ? target.checked : target.value;
const { name } = target;

if (['allowOptingOut', 'createZendeskTickets'].includes(name)) {
if (['allowOptingOut'].includes(name)) {
// Form.Radio expects string values, so convert back to a boolean here
setFormValues({ ...formValues, [name]: value === 'true' });
} else if (name === 'proctoringProvider') {
const newFormValues = { ...formValues, proctoringProvider: value };

if (value === 'proctortrack') {
setFormValues({ ...newFormValues, createZendeskTickets: false });
setFormValues(newFormValues);
setShowEscalationEmail(true);
} else if (value === 'software_secure') {
setFormValues({ ...newFormValues, createZendeskTickets: true });
setFormValues({ ...newFormValues });
setShowEscalationEmail(false);
} else if (isLtiProvider(value)) {
setFormValues(newFormValues);
Expand Down Expand Up @@ -116,7 +114,6 @@ const ProctoringSettings = ({ onClose }) => {
enable_proctored_exams: formValues.enableProctoredExams,
// lti providers are managed outside edx-platform, lti_external indicates this
proctoring_provider: isLtiProviderSelected ? 'lti_external' : selectedProvider,
create_zendesk_tickets: formValues.createZendeskTickets,
},
};
if (isEdxStaff) {
Expand Down Expand Up @@ -387,29 +384,6 @@ const ProctoringSettings = ({ onClose }) => {
</Form.Group>
</fieldset>
)}

{/* CREATE ZENDESK TICKETS */}
{ isEdxStaff && formValues.enableProctoredExams && !isLtiProviderSelected && (
<fieldset aria-describedby="createZendeskTicketsText">
<Form.Group controlId="formCreateZendeskTickets">
<Form.Label as="legend" className="font-weight-bold">
{intl.formatMessage(messages['authoring.proctoring.createzendesk.label'])}
</Form.Label>
<Form.RadioSet
name="createZendeskTickets"
value={formValues.createZendeskTickets.toString()}
onChange={handleChange}
>
<Form.Radio value="true" data-testid="createZendeskTicketsYes">
{intl.formatMessage(messages['authoring.proctoring.yes'])}
</Form.Radio>
<Form.Radio value="false" data-testid="createZendeskTicketsNo">
{intl.formatMessage(messages['authoring.proctoring.no'])}
</Form.Radio>
</Form.RadioSet>
</Form.Group>
</fieldset>
)}
</>
);
}
Expand Down Expand Up @@ -570,7 +544,6 @@ const ProctoringSettings = ({ onClose }) => {
proctoringProvider: selectedProvider,
enableProctoredExams: proctoredExamSettings.enable_proctored_exams,
allowOptingOut: proctoredExamSettings.allow_proctoring_opt_out,
createZendeskTickets: proctoredExamSettings.create_zendesk_tickets,
// The backend API may return null for the proctoringEscalationEmail value, which is the default.
// In order to keep our email input component controlled, we use the empty string as the default
// and perform this conversion during GETs and POSTs.
Expand Down
70 changes: 2 additions & 68 deletions plugins/course-apps/proctoring/Settings.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,36 +105,6 @@ describe('ProctoredExamSettings', () => {
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
});

it('Updates Zendesk ticket field if proctortrack is provider', async () => {
await waitFor(() => {
screen.getByDisplayValue('mockproc');
});
const selectElement = screen.getByDisplayValue('mockproc');
fireEvent.change(selectElement, { target: { value: 'proctortrack' } });
const zendeskTicketInput = screen.getByTestId('createZendeskTicketsNo');
expect(zendeskTicketInput.checked).toEqual(true);
});

it('Updates Zendesk ticket field if software_secure is provider', async () => {
await waitFor(() => {
screen.getByDisplayValue('mockproc');
});
const selectElement = screen.getByDisplayValue('mockproc');
fireEvent.change(selectElement, { target: { value: 'software_secure' } });
const zendeskTicketInput = screen.getByTestId('createZendeskTicketsYes');
expect(zendeskTicketInput.checked).toEqual(true);
});

it('Does not update zendesk ticket field for any other provider', async () => {
await waitFor(() => {
screen.getByDisplayValue('mockproc');
});
const selectElement = screen.getByDisplayValue('mockproc');
fireEvent.change(selectElement, { target: { value: 'mockproc' } });
const zendeskTicketInput = screen.getByTestId('createZendeskTicketsYes');
expect(zendeskTicketInput.checked).toEqual(true);
});

it('Hides all other fields when enabledProctorExam is false when first loaded', async () => {
cleanup();
// Overrides the handler defined in beforeEach.
Expand All @@ -161,8 +131,6 @@ describe('ProctoredExamSettings', () => {
expect(screen.queryByText('Allow Opting Out of Proctored Exams')).toBeNull();
expect(screen.queryByDisplayValue('mockproc')).toBeNull();
expect(screen.queryByTestId('escalationEmail')).toBeNull();
expect(screen.queryByTestId('createZendeskTicketsYes')).toBeNull();
expect(screen.queryByTestId('createZendeskTicketsNo')).toBeNull();
});

it('Hides all other fields when enableProctoredExams toggled to false', async () => {
Expand All @@ -172,8 +140,6 @@ describe('ProctoredExamSettings', () => {
expect(screen.queryByText('Allow opting out of proctored exams')).toBeDefined();
expect(screen.queryByDisplayValue('mockproc')).toBeDefined();
expect(screen.queryByTestId('escalationEmail')).toBeDefined();
expect(screen.queryByTestId('createZendeskTicketsYes')).toBeDefined();
expect(screen.queryByTestId('createZendeskTicketsNo')).toBeDefined();

let enabledProctoredExamCheck = screen.getAllByLabelText('Proctored exams', { exact: false })[0];
expect(enabledProctoredExamCheck.checked).toEqual(true);
Expand All @@ -183,8 +149,6 @@ describe('ProctoredExamSettings', () => {
expect(screen.queryByText('Allow opting out of proctored exams')).toBeNull();
expect(screen.queryByDisplayValue('mockproc')).toBeNull();
expect(screen.queryByTestId('escalationEmail')).toBeNull();
expect(screen.queryByTestId('createZendeskTicketsYes')).toBeNull();
expect(screen.queryByTestId('createZendeskTicketsNo')).toBeNull();
});

it('Hides unsupported fields when lti provider is selected', async () => {
Expand Down Expand Up @@ -527,18 +491,16 @@ describe('ProctoredExamSettings', () => {
});

describe('Toggles field visibility based on user permissions', () => {
it('Hides opting out and zendesk tickets for non edX staff', async () => {
it('Hides opting out for non edX staff', async () => {
setupApp(false);
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
expect(screen.queryByTestId('allowOptingOutYes')).toBeNull();
expect(screen.queryByTestId('createZendeskTicketsYes')).toBeNull();
});

it('Shows opting out and zendesk tickets for edX staff', async () => {
it('Shows opting out for edX staff', async () => {
setupApp(true);
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
expect(screen.queryByTestId('allowOptingOutYes')).not.toBeNull();
expect(screen.queryByTestId('createZendeskTicketsYes')).not.toBeNull();
});
});

Expand Down Expand Up @@ -624,7 +586,6 @@ describe('ProctoredExamSettings', () => {
allow_proctoring_opt_out: false,
proctoring_provider: 'proctortrack',
proctoring_escalation_email: 'proctortrack@example.com',
create_zendesk_tickets: false,
},
});

Expand All @@ -651,7 +612,6 @@ describe('ProctoredExamSettings', () => {
enable_proctored_exams: true,
allow_proctoring_opt_out: false,
proctoring_provider: 'mockproc',
create_zendesk_tickets: true,
},
});

Expand Down Expand Up @@ -692,7 +652,6 @@ describe('ProctoredExamSettings', () => {
enable_proctored_exams: true,
allow_proctoring_opt_out: false,
proctoring_provider: 'lti_external',
create_zendesk_tickets: true,
},
});

Expand Down Expand Up @@ -722,7 +681,6 @@ describe('ProctoredExamSettings', () => {
enable_proctored_exams: true,
allow_proctoring_opt_out: false,
proctoring_provider: 'mockproc',
create_zendesk_tickets: true,
},
});

Expand All @@ -744,7 +702,6 @@ describe('ProctoredExamSettings', () => {
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',
Expand All @@ -762,7 +719,6 @@ describe('ProctoredExamSettings', () => {
enable_proctored_exams: true,
allow_proctoring_opt_out: false,
proctoring_provider: 'mockproc',
create_zendesk_tickets: true,
},
});

Expand Down Expand Up @@ -862,27 +818,5 @@ describe('ProctoredExamSettings', () => {
expect(document.activeElement).toEqual(successAlert);
});
});

it('Include Zendesk ticket in post request if user is not an admin', async () => {
// use non-admin user for test
const isAdmin = false;
setupApp(isAdmin);

await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
// Make a change to the proctoring provider
const selectElement = screen.getByDisplayValue('mockproc');
fireEvent.change(selectElement, { target: { value: 'proctortrack' } });
const submitButton = screen.getByTestId('submissionButton');
fireEvent.click(submitButton);
expect(axiosMock.history.post.length).toBe(1);
expect(JSON.parse(axiosMock.history.post[0].data)).toEqual({
proctored_exam_settings: {
enable_proctored_exams: true,
proctoring_provider: 'proctortrack',
proctoring_escalation_email: 'test@example.com',
create_zendesk_tickets: false,
},
});
});
});
});
5 changes: 0 additions & 5 deletions plugins/course-apps/proctoring/messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,6 @@ const messages = defineMessages({
defaultMessage: 'Allow learners to opt out of proctoring on proctored exams',
description: 'Label for radio selection allowing proctored exam opt out',
},
'authoring.proctoring.createzendesk.label': {
id: 'authoring.proctoring.createzendesk.label',
defaultMessage: 'Create Zendesk tickets for suspicious attempts',
description: 'Label for Zendesk ticket creation radio select.',
},
'authoring.proctoring.error.single': {
id: 'authoring.proctoring.error.single',
defaultMessage: 'There is 1 error in this form.',
Expand Down