diff --git a/src/course-header/Header.jsx b/src/course-header/Header.jsx index bd77469e..b77702c8 100644 --- a/src/course-header/Header.jsx +++ b/src/course-header/Header.jsx @@ -2,10 +2,12 @@ import React, { useContext } from 'react'; import PropTypes from 'prop-types'; import { useEnterpriseConfig } from '@edx/frontend-enterprise'; import { getConfig } from '@edx/frontend-platform'; +import { injectIntl, intlShape } from '@edx/frontend-platform/i18n'; import { AppContext } from '@edx/frontend-platform/react'; import AnonymousUserMenu from './AnonymousUserMenu'; import AuthenticatedUserDropdown from './AuthenticatedUserDropdown'; +import messages from './messages'; function LinkedLogo({ href, @@ -27,7 +29,7 @@ LinkedLogo.propTypes = { }; function Header({ - courseOrg, courseNumber, courseTitle, + courseOrg, courseNumber, courseTitle, intl, }) { const { authenticatedUser } = useContext(AppContext); @@ -58,6 +60,7 @@ function Header({ return (
+ {intl.formatMessage(messages.skipNavLink)}
{headerLogo}
@@ -82,6 +85,7 @@ Header.propTypes = { courseOrg: PropTypes.string, courseNumber: PropTypes.string, courseTitle: PropTypes.string, + intl: intlShape.isRequired, }; Header.defaultProps = { @@ -90,4 +94,4 @@ Header.defaultProps = { courseTitle: null, }; -export default Header; +export default injectIntl(Header); diff --git a/src/course-header/messages.js b/src/course-header/messages.js index 07d5de93..e35d61ac 100644 --- a/src/course-header/messages.js +++ b/src/course-header/messages.js @@ -31,6 +31,11 @@ const messages = defineMessages({ defaultMessage: 'Order History', description: 'The text for the user menu Order History navigation link.', }, + skipNavLink: { + id: 'header.navigation.skipNavLink', + defaultMessage: 'Skip to main content.', + description: 'A link used by screen readers to allow users to skip to the main content of the page.', + }, signOut: { id: 'header.menu.signOut.label', defaultMessage: 'Sign Out', diff --git a/src/course-home/data/__factories__/courseHomeMetadata.factory.js b/src/course-home/data/__factories__/courseHomeMetadata.factory.js index 67d2ab12..4db203d9 100644 --- a/src/course-home/data/__factories__/courseHomeMetadata.factory.js +++ b/src/course-home/data/__factories__/courseHomeMetadata.factory.js @@ -67,6 +67,16 @@ Factory.define('courseHomeMetadata') }, { courseId, path: 'instructor' }, ), + Factory.build( + 'tab', + { + title: 'Dates', + priority: 5, + slug: 'dates', + type: 'dates', + }, + { courseId, path: 'dates' }, + ), ]; return tabs.map( diff --git a/src/course-home/data/__snapshots__/redux.test.js.snap b/src/course-home/data/__snapshots__/redux.test.js.snap index d2463b04..403b2a31 100644 --- a/src/course-home/data/__snapshots__/redux.test.js.snap +++ b/src/course-home/data/__snapshots__/redux.test.js.snap @@ -52,6 +52,11 @@ Object { "title": "Instructor", "url": "http://localhost:18000/courses/course-v1:edX+DemoX+Demo_Course_1/instructor", }, + Object { + "slug": "dates", + "title": "Dates", + "url": "http://localhost:18000/courses/course-v1:edX+DemoX+Demo_Course_1/dates", + }, ], "title": "Demonstration Course", }, @@ -333,6 +338,11 @@ Object { "title": "Instructor", "url": "http://localhost:18000/courses/course-v1:edX+DemoX+Demo_Course_1/instructor", }, + Object { + "slug": "dates", + "title": "Dates", + "url": "http://localhost:18000/courses/course-v1:edX+DemoX+Demo_Course_1/dates", + }, ], "title": "Demonstration Course", }, diff --git a/src/course-home/outline-tab/DateSummary.jsx b/src/course-home/outline-tab/DateSummary.jsx index a0d36480..63be8550 100644 --- a/src/course-home/outline-tab/DateSummary.jsx +++ b/src/course-home/outline-tab/DateSummary.jsx @@ -13,7 +13,7 @@ export default function DateSummary({ const linkedTitle = dateBlock.link && isLearnerAssignment(dateBlock); const timezoneFormatArgs = userTimezone ? { timeZone: userTimezone } : {}; return ( -
+
  • @@ -39,7 +39,7 @@ export default function DateSummary({ {!linkedTitle && dateBlock.link && {dateBlock.linkText}}
    -
  • + ); } diff --git a/src/course-home/outline-tab/OutlineTab.jsx b/src/course-home/outline-tab/OutlineTab.jsx index 58ce6762..4fe9f15b 100644 --- a/src/course-home/outline-tab/OutlineTab.jsx +++ b/src/course-home/outline-tab/OutlineTab.jsx @@ -146,15 +146,17 @@ function OutlineTab({ intl }) {
    - {courses[rootCourseId].sectionIds.map((sectionId) => ( -
    - ))} +
      + {courses[rootCourseId].sectionIds.map((sectionId) => ( +
      + ))} +
    )} diff --git a/src/course-home/outline-tab/OutlineTab.test.jsx b/src/course-home/outline-tab/OutlineTab.test.jsx index f50727b7..7fe863e0 100644 --- a/src/course-home/outline-tab/OutlineTab.test.jsx +++ b/src/course-home/outline-tab/OutlineTab.test.jsx @@ -71,7 +71,7 @@ describe('Outline Tab', () => { }, }); await fetchAndRender(); - expect(screen.getByRole('link', { name: 'Resume Course' })).toBeInTheDocument(); + expect(screen.getByRole('link', { name: 'Resume course' })).toBeInTheDocument(); }); it('expands section that contains resume block', async () => { @@ -87,7 +87,7 @@ describe('Outline Tab', () => { it('handles expand/collapse all button click', async () => { await fetchAndRender(); // Button renders as "Expand All" - const expandButton = screen.getByRole('button', { name: 'Expand All' }); + const expandButton = screen.getByRole('button', { name: 'Expand all' }); expect(expandButton).toBeInTheDocument(); // Section initially renders collapsed diff --git a/src/course-home/outline-tab/Section.jsx b/src/course-home/outline-tab/Section.jsx index ea931a48..e8152862 100644 --- a/src/course-home/outline-tab/Section.jsx +++ b/src/course-home/outline-tab/Section.jsx @@ -39,23 +39,27 @@ function Section({ }, []); const sectionTitle = ( -
    - {complete ? ( -