Skip to content

Commit 31b02d7

Browse files
feat: disable completion item icons on flag (#1714)
* feat: base modifications to disable completion checks when flag enabled * chore: started updating tests * chore: udpated tests * chore: added missing negative test --------- Co-authored-by: Adolfo R. Brandes <[email protected]>
1 parent 67bb54a commit 31b02d7

File tree

13 files changed

+70
-32
lines changed

13 files changed

+70
-32
lines changed

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"snapshot": "fedx-scripts jest --updateSnapshot",
1919
"start": "fedx-scripts webpack-dev-server --progress",
2020
"dev": "PUBLIC_PATH=/learning/ MFE_CONFIG_API_URL='http://localhost:8000/api/mfe_config/v1' fedx-scripts webpack-dev-server --progress --host apps.local.openedx.io",
21-
"test": "fedx-scripts jest --coverage --passWithNoTests",
21+
"test": "NODE_ENV=test fedx-scripts jest --coverage --passWithNoTests",
2222
"test:watch": "fedx-scripts jest --watch --passWithNoTests",
2323
"types": "tsc --noEmit"
2424
},
@@ -97,4 +97,4 @@
9797
],
9898
"normalizeFilenames": "^.+?(\\..+?)\\.\\w+$"
9999
}
100-
}
100+
}

src/courseware/course/sidebar/sidebars/course-outline/components/CompletionIcon.jsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ import {
66

77
import { DashedCircleIcon } from '../icons';
88

9-
const CompletionIcon = ({ completionStat: { completed = 0, total = 0 } }) => {
9+
const CompletionIcon = ({ completionStat: { completed = 0, total = 0 }, enabled }) => {
1010
const percentage = total !== 0 ? Math.min((completed / total) * 100, 100) : 0;
1111
const remainder = 100 - percentage;
1212

1313
switch (true) {
14-
case !completed:
14+
case !completed || !enabled:
1515
return <LmsCompletionSolidIcon className="text-gray-300" data-testid="completion-solid-icon" />;
1616
case completed === total:
1717
return <CheckCircleIcon className="text-success" data-testid="check-circle-icon" />;
@@ -25,6 +25,7 @@ CompletionIcon.propTypes = {
2525
completed: PropTypes.number,
2626
total: PropTypes.number,
2727
}).isRequired,
28+
enabled: PropTypes.bool.isRequired,
2829
};
2930

3031
export default CompletionIcon;

src/courseware/course/sidebar/sidebars/course-outline/components/CompletionIcon.test.jsx

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,33 @@ import { render, screen } from '@testing-library/react';
33
import CompletionIcon from './CompletionIcon';
44

55
describe('CompletionIcon', () => {
6-
it('renders check circle icon when completion is equal to total', () => {
6+
it('renders check circle icon when completion is equal to total and completion tracking is enabled', () => {
77
const completionStat = { completed: 5, total: 5 };
8-
render(<CompletionIcon completionStat={completionStat} />);
8+
render(<CompletionIcon completionStat={completionStat} enabled />);
99
expect(screen.getByTestId('check-circle-icon')).toBeInTheDocument();
1010
});
1111

12-
it('renders dashed circle icon when completion is between 0 and total', () => {
12+
it('renders dashed circle icon when completion is between 0 and total and completion tracking is enabled', () => {
1313
const completionStat = { completed: 2, total: 5 };
14-
render(<CompletionIcon completionStat={completionStat} />);
14+
render(<CompletionIcon completionStat={completionStat} enabled />);
1515
expect(screen.getByTestId('dashed-circle-icon')).toBeInTheDocument();
1616
});
1717

18-
it('renders completion solid icon when completion is 0', () => {
18+
it('renders completion solid icon when completion is between 0 and total and completion tracking is not enabled', () => {
19+
const completionStat = { completed: 2, total: 5 };
20+
render(<CompletionIcon completionStat={completionStat} enabled={false} />);
21+
expect(screen.getByTestId('completion-solid-icon')).toBeInTheDocument();
22+
});
23+
24+
it('renders completion solid icon when completion is 0 and enabled', () => {
25+
const completionStat = { completed: 0, total: 5 };
26+
render(<CompletionIcon completionStat={completionStat} enabled />);
27+
expect(screen.getByTestId('completion-solid-icon')).toBeInTheDocument();
28+
});
29+
30+
it('renders completion solid icon when completion is at any value and not enabled', () => {
1931
const completionStat = { completed: 0, total: 5 };
20-
render(<CompletionIcon completionStat={completionStat} />);
32+
render(<CompletionIcon completionStat={completionStat} enabled={false} />);
2133
expect(screen.getByTestId('completion-solid-icon')).toBeInTheDocument();
2234
});
2335
});

src/courseware/course/sidebar/sidebars/course-outline/components/SidebarSection.jsx

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,24 @@ const SidebarSection = ({ section, handleSelectSection }) => {
1818
completionStat,
1919
} = section;
2020

21-
const { activeSequenceId } = useCourseOutlineSidebar();
21+
const { activeSequenceId, isEnabledCompletionTracking } = useCourseOutlineSidebar();
2222
const isActiveSection = sequenceIds.includes(activeSequenceId);
2323

2424
const sectionTitle = (
2525
<>
2626
<div className="col-auto p-0">
27-
<CompletionIcon completionStat={completionStat} />
27+
<CompletionIcon completionStat={completionStat} enabled={isEnabledCompletionTracking} />
2828
</div>
2929
<div className="col-10 ml-3 p-0 flex-grow-1 text-dark-500 text-left text-break">
3030
{title}
31-
<span className="sr-only">
32-
, {intl.formatMessage(complete
33-
? courseOutlineMessages.completedSection
34-
: courseOutlineMessages.incompleteSection)}
35-
</span>
31+
{isEnabledCompletionTracking && (
32+
<span className="sr-only">
33+
, {intl.formatMessage(complete
34+
? courseOutlineMessages.completedSection
35+
: courseOutlineMessages.incompleteSection)}
36+
</span>
37+
)}
38+
3639
</div>
3740
</>
3841
);

src/courseware/course/sidebar/sidebars/course-outline/components/SidebarSequence.jsx

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,22 +28,24 @@ const SidebarSequence = ({
2828
} = sequence;
2929

3030
const [open, setOpen] = useState(defaultOpen);
31-
const { activeSequenceId, units } = useCourseOutlineSidebar();
31+
const { activeSequenceId, units, isEnabledCompletionTracking } = useCourseOutlineSidebar();
3232
const isActiveSequence = id === activeSequenceId;
3333

3434
const sectionTitle = (
3535
<>
3636
<div className="col-auto p-0" style={{ fontSize: '1.1rem' }}>
37-
<CompletionIcon completionStat={completionStat} />
37+
<CompletionIcon completionStat={completionStat} enabled={isEnabledCompletionTracking} />
3838
</div>
3939
<div className="col-9 d-flex flex-column flex-grow-1 ml-3 mr-auto p-0 text-left">
4040
<span className="align-middle text-dark-500">{title}</span>
4141
{specialExamInfo && <span className="align-middle small text-muted">{specialExamInfo}</span>}
42-
<span className="sr-only">
43-
, {intl.formatMessage(complete
44-
? courseOutlineMessages.completedAssignment
45-
: courseOutlineMessages.incompleteAssignment)}
46-
</span>
42+
{isEnabledCompletionTracking && (
43+
<span className="sr-only">
44+
, {intl.formatMessage(complete
45+
? courseOutlineMessages.completedAssignment
46+
: courseOutlineMessages.incompleteAssignment)}
47+
</span>
48+
)}
4749
</div>
4850
</>
4951
);
@@ -69,6 +71,7 @@ const SidebarSequence = ({
6971
activeUnitId={activeUnitId}
7072
isFirst={index === 0}
7173
isLocked={type === UNIT_ICON_TYPES.lock}
74+
isCompletionTrackingEnabled={isEnabledCompletionTracking}
7275
/>
7376
))}
7477
</ol>

src/courseware/course/sidebar/sidebars/course-outline/components/SidebarSequence.test.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ describe('<SidebarSequence />', () => {
6666
expect(screen.queryByText(unit.title)).not.toBeInTheDocument();
6767
});
6868

69-
it('renders correctly when sequence is not collapsed and complete', async () => {
69+
it('renders correctly when sequence is not collapsed and complete and completion tracking enabled', async () => {
7070
const user = userEvent.setup();
7171
await initTestStore();
7272
renderWithProvider({

src/courseware/course/sidebar/sidebars/course-outline/components/SidebarUnit.jsx

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ const SidebarUnit = ({
1515
isActive,
1616
isLocked,
1717
activeUnitId,
18+
isCompletionTrackingEnabled,
1819
}) => {
1920
const intl = useIntl();
2021
const {
@@ -24,6 +25,7 @@ const SidebarUnit = ({
2425
} = unit;
2526

2627
const iconType = isLocked ? UNIT_ICON_TYPES.lock : icon;
28+
const completeAndEnabled = complete && isCompletionTrackingEnabled;
2729

2830
return (
2931
<li className={classNames({ 'bg-info-100': isActive, 'border-top border-light': !isFirst })}>
@@ -36,15 +38,17 @@ const SidebarUnit = ({
3638
}}
3739
>
3840
<div className="col-auto p-0">
39-
<UnitIcon type={iconType} isCompleted={complete} />
41+
<UnitIcon type={iconType} isCompleted={completeAndEnabled} />
4042
</div>
4143
<div className="col-10 p-0 ml-3 text-break">
4244
<span className="align-middle">
4345
{title}
4446
</span>
45-
<span className="sr-only">
46-
, {intl.formatMessage(complete ? messages.completedUnit : messages.incompleteUnit)}
47-
</span>
47+
{isCompletionTrackingEnabled && (
48+
<span className="sr-only">
49+
, {intl.formatMessage(complete ? messages.completedUnit : messages.incompleteUnit)}
50+
</span>
51+
)}
4852
</div>
4953
</UnitLinkWrapper>
5054
</li>
@@ -66,6 +70,7 @@ SidebarUnit.propTypes = {
6670
courseId: PropTypes.string.isRequired,
6771
sequenceId: PropTypes.string.isRequired,
6872
activeUnitId: PropTypes.string.isRequired,
73+
isCompletionTrackingEnabled: PropTypes.bool.isRequired,
6974
};
7075

7176
export default SidebarUnit;

src/courseware/course/sidebar/sidebars/course-outline/components/SidebarUnit.test.jsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ describe('<SidebarUnit />', () => {
5050
unit={{ ...unit, icon: 'video', isLocked: false }}
5151
isActive={false}
5252
activeUnitId={unit.id}
53+
isCompletionTrackingEnabled
5354
{...props}
5455
/>
5556
</MemoryRouter>
@@ -68,7 +69,7 @@ describe('<SidebarUnit />', () => {
6869
expect(container.querySelector('.text-success')).not.toBeInTheDocument();
6970
});
7071

71-
it('renders correctly when unit is complete', async () => {
72+
it('renders correctly when unit is complete and tracking enabled', async () => {
7273
await initTestStore();
7374
const container = renderWithProvider({ unit: { ...unit, complete: true } });
7475

src/courseware/course/sidebar/sidebars/course-outline/hooks.jsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@ import { ID } from './constants';
2222
export const useCourseOutlineSidebar = () => {
2323
const dispatch = useDispatch();
2424
const isCollapsedOutlineSidebar = window.sessionStorage.getItem('hideCourseOutlineSidebar');
25-
const { enableNavigationSidebar: isEnabledSidebar } = useSelector(getCoursewareOutlineSidebarSettings);
25+
const {
26+
enableNavigationSidebar: isEnabledSidebar,
27+
enableCompletionTracking: isEnabledCompletionTracking,
28+
} = useSelector(getCoursewareOutlineSidebarSettings);
2629
const courseOutlineShouldUpdate = useSelector(getCourseOutlineShouldUpdate);
2730
const courseOutlineStatus = useSelector(getCourseOutlineStatus);
2831
const sequenceStatus = useSelector(getSequenceStatus);
@@ -110,6 +113,7 @@ export const useCourseOutlineSidebar = () => {
110113
currentSidebar,
111114
shouldDisplayFullScreen,
112115
isEnabledSidebar,
116+
isEnabledCompletionTracking,
113117
isOpen,
114118
setIsOpen,
115119
handleToggleCollapse,

src/courseware/data/api.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,5 +115,6 @@ export async function getCoursewareOutlineSidebarToggles(courseId) {
115115
return {
116116
enable_navigation_sidebar: data.enable_navigation_sidebar || false,
117117
always_open_auxiliary_sidebar: data.always_open_auxiliary_sidebar || false,
118+
enable_completion_tracking: data.enable_completion_tracking || false,
118119
};
119120
}

0 commit comments

Comments
 (0)