diff --git a/src/courseware/course/sidebar/sidebars/course-outline/components/SidebarUnit.jsx b/src/courseware/course/sidebar/sidebars/course-outline/components/SidebarUnit.jsx index 1d34ee63c0..c01a575f0a 100644 --- a/src/courseware/course/sidebar/sidebars/course-outline/components/SidebarUnit.jsx +++ b/src/courseware/course/sidebar/sidebars/course-outline/components/SidebarUnit.jsx @@ -7,6 +7,7 @@ import { sendTrackEvent, sendTrackingLogEvent } from '@edx/frontend-platform/ana import { checkBlockCompletion } from '@src/courseware/data'; import { getCourseOutline } from '@src/courseware/data/selectors'; +import { useCourseOutlineSidebar } from '../hooks'; import messages from '../messages'; import UnitIcon, { UNIT_ICON_TYPES } from './UnitIcon'; @@ -28,6 +29,7 @@ const SidebarUnit = ({ } = unit; const dispatch = useDispatch(); const { sequences = {} } = useSelector(getCourseOutline); + const { handleToggleCollapse, shouldDisplayFullScreen } = useCourseOutlineSidebar(); const logEvent = (eventName, widgetPlacement) => { const findSequenceByUnitId = (unitId) => Object.values(sequences).find(seq => seq.unitIds.includes(unitId)); @@ -53,6 +55,11 @@ const SidebarUnit = ({ const handleClick = () => { logEvent('edx.ui.lms.sequence.tab_selected', 'left'); dispatch(checkBlockCompletion(courseId, sequenceId, activeUnitId)); + + // Hide the sidebar after selecting a unit on a mobile device. + if (shouldDisplayFullScreen) { + handleToggleCollapse(); + } }; const iconType = isLocked ? UNIT_ICON_TYPES.lock : icon; diff --git a/src/courseware/course/sidebar/sidebars/course-outline/components/SidebarUnit.test.jsx b/src/courseware/course/sidebar/sidebars/course-outline/components/SidebarUnit.test.jsx index c46ef0eda2..8bfd3c7a81 100644 --- a/src/courseware/course/sidebar/sidebars/course-outline/components/SidebarUnit.test.jsx +++ b/src/courseware/course/sidebar/sidebars/course-outline/components/SidebarUnit.test.jsx @@ -7,6 +7,8 @@ import { sendTrackEvent, sendTrackingLogEvent } from '@edx/frontend-platform/ana import { initializeMockApp, initializeTestStore } from '@src/setupTest'; import SidebarUnit from './SidebarUnit'; +import SidebarContext from '../../../SidebarContext'; +import { ID } from '../constants'; jest.mock('@edx/frontend-platform/analytics', () => ({ sendTrackEvent: jest.fn(), @@ -20,6 +22,13 @@ describe('', () => { let unit; let sequenceId; + // A default context for desktop mode. + const defaultSidebarContext = { + toggleSidebar: jest.fn(), + shouldDisplayFullScreen: false, + currentSidebar: ID, + }; + const initTestStore = async (options) => { store = await initializeTestStore(options); const state = store.getState(); @@ -28,21 +37,23 @@ describe('', () => { unit = state.courseware.courseOutline.units[sequence.unitIds[0]]; }; - function renderWithProvider(props = {}) { + function renderWithProvider(props = {}, sidebarContext = defaultSidebarContext) { const { container } = render( - + + + , @@ -87,21 +98,42 @@ describe('', () => { expect(screen.getByText(unit.title)).toBeInTheDocument(); }); - it('sends log event correctly when unit is clicked', async () => { - await initTestStore(); - renderWithProvider({ unit: { ...unit } }); - const logData = { - id: unit.id, - current_tab: 1, - tab_count: 1, - target_id: unit.id, - target_tab: 1, - widget_placement: 'left', - }; - - userEvent.click(screen.getByText(unit.title)); - - expect(sendTrackEvent).toHaveBeenCalledWith('edx.ui.lms.sequence.tab_selected', logData); - expect(sendTrackingLogEvent).toHaveBeenCalledWith('edx.ui.lms.sequence.tab_selected', logData); + describe('When a unit is clicked', () => { + it('sends log event correctly', async () => { + await initTestStore(); + renderWithProvider({ unit: { ...unit } }); + const logData = { + id: unit.id, + current_tab: 1, + tab_count: 1, + target_id: unit.id, + target_tab: 1, + widget_placement: 'left', + }; + + userEvent.click(screen.getByText(unit.title)); + + expect(sendTrackEvent).toHaveBeenCalledWith('edx.ui.lms.sequence.tab_selected', logData); + expect(sendTrackingLogEvent).toHaveBeenCalledWith('edx.ui.lms.sequence.tab_selected', logData); + }); + + it('leaves sidebar open in desktop mode', async () => { + await initTestStore(); + renderWithProvider({ unit: { ...unit } }); + userEvent.click(screen.getByText(unit.title)); + + expect(defaultSidebarContext.toggleSidebar).not.toHaveBeenCalled(); + expect(window.sessionStorage.getItem('hideCourseOutlineSidebar')).toBeNull(); + }); + + it('closes sidebar on mobile devices', async () => { + await initTestStore(); + renderWithProvider({ unit: { ...unit } }, { ...defaultSidebarContext, shouldDisplayFullScreen: true }); + userEvent.click(screen.getByText(unit.title)); + + expect(defaultSidebarContext.toggleSidebar).toHaveBeenCalledTimes(1); + expect(defaultSidebarContext.toggleSidebar).toHaveBeenCalledWith(null); + expect(window.sessionStorage.getItem('hideCourseOutlineSidebar')).toEqual('true'); + }); }); });