fix: [AA-1087] defer goals widget for proctoring (#727)
fix: [AA-1087] defer goals widget for proctoring - pause showing goals widget while proctor info panel awaits callback. - Implement tests to check that goals show up when proctoring does not - small refactoring of LearningGoalButton to eliminate test warnings
This commit is contained in:
@@ -453,6 +453,7 @@ Object {
|
||||
"datesWidget": Object {
|
||||
"courseDateBlocks": Array [],
|
||||
},
|
||||
"enableProctoredExams": undefined,
|
||||
"enrollAlert": Object {
|
||||
"canEnroll": true,
|
||||
"extraText": "Contact the administrator.",
|
||||
|
||||
@@ -343,6 +343,7 @@ export async function getOutlineTabData(courseId) {
|
||||
const courseTools = camelCaseObject(data.course_tools);
|
||||
const datesBannerInfo = camelCaseObject(data.dates_banner_info);
|
||||
const datesWidget = camelCaseObject(data.dates_widget);
|
||||
const enableProctoredExams = data.enable_proctored_exams;
|
||||
const enrollAlert = camelCaseObject(data.enroll_alert);
|
||||
const enrollmentMode = data.enrollment_mode;
|
||||
const handoutsHtml = data.handouts_html;
|
||||
@@ -366,6 +367,7 @@ export async function getOutlineTabData(courseId) {
|
||||
datesWidget,
|
||||
enrollAlert,
|
||||
enrollmentMode,
|
||||
enableProctoredExams,
|
||||
handoutsHtml,
|
||||
hasScheduledContent,
|
||||
hasEnded,
|
||||
|
||||
@@ -62,10 +62,11 @@ function OutlineTab({ intl }) {
|
||||
datesWidget: {
|
||||
courseDateBlocks,
|
||||
},
|
||||
enableProctoredExams,
|
||||
offer,
|
||||
resumeCourse: {
|
||||
url: resumeCourseUrl,
|
||||
},
|
||||
offer,
|
||||
timeOffsetMillis,
|
||||
verifiedMode,
|
||||
} = useModel('outline', courseId);
|
||||
@@ -73,6 +74,9 @@ function OutlineTab({ intl }) {
|
||||
const [deprecatedCourseGoalToDisplay, setDeprecatedCourseGoalToDisplay] = useState(selectedGoal);
|
||||
const [goalToastHeader, setGoalToastHeader] = useState('');
|
||||
const [expandAll, setExpandAll] = useState(false);
|
||||
// Defer showing the goal widget until the ProctoringInfoPanel is either shown or determined as not showing
|
||||
// to avoid components bouncing around too much as screen is displayed
|
||||
const [proctorPanelResolved, setProctorPanelResolved] = useState(!enableProctoredExams);
|
||||
|
||||
const eventProperties = {
|
||||
org_key: org,
|
||||
@@ -200,6 +204,7 @@ function OutlineTab({ intl }) {
|
||||
<ProctoringInfoPanel
|
||||
courseId={courseId}
|
||||
username={username}
|
||||
isResolved={() => setProctorPanelResolved(true)}
|
||||
/>
|
||||
{deprecatedCourseGoalToDisplay && goalOptions && goalOptions.length > 0 && (
|
||||
<UpdateGoalSelector
|
||||
@@ -210,7 +215,7 @@ function OutlineTab({ intl }) {
|
||||
setGoalToastHeader={(newHeader) => { setGoalToastHeader(newHeader); }}
|
||||
/>
|
||||
)}
|
||||
{weeklyLearningGoalEnabled && (
|
||||
{proctorPanelResolved && weeklyLearningGoalEnabled && (
|
||||
<WeeklyLearningGoalCard
|
||||
daysPerWeek={selectedGoal && 'daysPerWeek' in selectedGoal ? selectedGoal.daysPerWeek : null}
|
||||
subscribedToReminders={selectedGoal && 'subscribedToReminders' in selectedGoal ? selectedGoal.subscribedToReminders : false}
|
||||
|
||||
@@ -513,19 +513,55 @@ describe('Outline Tab', () => {
|
||||
expect(screen.queryByText(messages.goalReminderDetail.defaultMessage)).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
describe('weekly learning goal is already set', () => {
|
||||
beforeEach(async () => {
|
||||
setTabData({
|
||||
course_goals: {
|
||||
weekly_learning_goal_enabled: true,
|
||||
selected_goal: {
|
||||
subscribed_to_reminders: true,
|
||||
days_per_week: 3,
|
||||
},
|
||||
|
||||
it('has button for weekly learning goal selected', async () => {
|
||||
setTabData({
|
||||
course_goals: {
|
||||
weekly_learning_goal_enabled: true,
|
||||
selected_goal: {
|
||||
subscribed_to_reminders: true,
|
||||
days_per_week: 3,
|
||||
},
|
||||
});
|
||||
await fetchAndRender();
|
||||
},
|
||||
});
|
||||
await fetchAndRender();
|
||||
|
||||
const button = await screen.queryByTestId('weekly-learning-goal-input-Regular');
|
||||
expect(button).toBeInTheDocument();
|
||||
expect(button).toHaveClass('flag-button-selected');
|
||||
});
|
||||
|
||||
it('renders weekly learning goal card if ProctoringInfoPanel is not shown', async () => {
|
||||
setTabData({
|
||||
course_goals: {
|
||||
weekly_learning_goal_enabled: true,
|
||||
},
|
||||
});
|
||||
axiosMock.onGet(proctoringInfoUrl).reply(404);
|
||||
await fetchAndRender();
|
||||
expect(screen.queryByTestId('weekly-learning-goal-card')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders weekly learning goal card if ProctoringInfoPanel is not enabled', async () => {
|
||||
setTabData({
|
||||
course_goals: {
|
||||
weekly_learning_goal_enabled: true,
|
||||
enableProctoredExams: false,
|
||||
},
|
||||
});
|
||||
await fetchAndRender();
|
||||
expect(screen.queryByTestId('weekly-learning-goal-card')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders weekly learning goal card if ProctoringInfoPanel is enabled', async () => {
|
||||
setTabData({
|
||||
course_goals: {
|
||||
weekly_learning_goal_enabled: true,
|
||||
enableProctoredExams: true,
|
||||
},
|
||||
});
|
||||
await fetchAndRender();
|
||||
expect(screen.queryByTestId('weekly-learning-goal-card')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1172,6 +1208,7 @@ describe('Outline Tab', () => {
|
||||
|
||||
it('does not appear for 404', async () => {
|
||||
axiosMock.onGet(proctoringInfoUrl).reply(404);
|
||||
await fetchAndRender();
|
||||
expect(screen.queryByRole('link', { name: 'Review instructions and system requirements' })).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ import messages from '../messages';
|
||||
|
||||
function LearningGoalButton({
|
||||
level,
|
||||
currentGoal,
|
||||
isSelected,
|
||||
handleSelect,
|
||||
intl,
|
||||
}) {
|
||||
@@ -43,14 +43,14 @@ function LearningGoalButton({
|
||||
title={intl.formatMessage(values.title)}
|
||||
text={intl.formatMessage(values.text)}
|
||||
handleSelect={() => handleSelect(values.daysPerWeek)}
|
||||
isSelected={currentGoal === values.daysPerWeek}
|
||||
isSelected={isSelected}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
LearningGoalButton.propTypes = {
|
||||
level: PropTypes.string.isRequired,
|
||||
currentGoal: PropTypes.number.isRequired,
|
||||
isSelected: PropTypes.bool.isRequired,
|
||||
handleSelect: PropTypes.func.isRequired,
|
||||
intl: intlShape.isRequired,
|
||||
};
|
||||
|
||||
@@ -8,7 +8,9 @@ import { Button } from '@edx/paragon';
|
||||
import messages from '../messages';
|
||||
import { getProctoringInfoData } from '../../data/api';
|
||||
|
||||
function ProctoringInfoPanel({ courseId, username, intl }) {
|
||||
function ProctoringInfoPanel({
|
||||
courseId, username, intl, isResolved,
|
||||
}) {
|
||||
const [link, setLink] = useState('');
|
||||
const [onboardingPastDue, setOnboardingPastDue] = useState(false);
|
||||
const [showInfoPanel, setShowInfoPanel] = useState(false);
|
||||
@@ -95,7 +97,13 @@ function ProctoringInfoPanel({ courseId, username, intl }) {
|
||||
setOnboardingPastDue(response.onboarding_past_due);
|
||||
}
|
||||
},
|
||||
);
|
||||
)
|
||||
.catch(() => {
|
||||
/* Do nothing. API throws 404 when class does not have proctoring */
|
||||
})
|
||||
.finally(() => {
|
||||
isResolved();
|
||||
});
|
||||
}, []);
|
||||
|
||||
let onboardingExamButton = null;
|
||||
@@ -186,6 +194,7 @@ ProctoringInfoPanel.propTypes = {
|
||||
courseId: PropTypes.string.isRequired,
|
||||
username: PropTypes.string,
|
||||
intl: intlShape.isRequired,
|
||||
isResolved: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
ProctoringInfoPanel.defaultProps = {
|
||||
|
||||
@@ -63,17 +63,17 @@ function WeeklyLearningGoalCard({
|
||||
>
|
||||
<LearningGoalButton
|
||||
level="casual"
|
||||
currentGoal={daysPerWeekGoal}
|
||||
isSelected={daysPerWeekGoal === 1}
|
||||
handleSelect={handleSelect}
|
||||
/>
|
||||
<LearningGoalButton
|
||||
level="regular"
|
||||
currentGoal={daysPerWeekGoal}
|
||||
isSelected={daysPerWeekGoal === 3}
|
||||
handleSelect={handleSelect}
|
||||
/>
|
||||
<LearningGoalButton
|
||||
level="intense"
|
||||
currentGoal={daysPerWeekGoal}
|
||||
isSelected={daysPerWeekGoal === 5}
|
||||
handleSelect={handleSelect}
|
||||
/>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user