richie-education 3.3.1-dev12 → 3.3.1-dev13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -18,17 +18,6 @@ const messages = defineMessages({
18
18
  'Message displayed on the top of course runs list on syllabus when there is 0 or multiple course runs opened',
19
19
  defaultMessage: 'Course runs',
20
20
  },
21
- noCourseRuns: {
22
- id: 'components.SyllabusAsideList.noCourseRuns',
23
- description: 'Message displayed on syllabus when there are no course runs to show',
24
- defaultMessage: 'No course runs',
25
- },
26
- noOtherCourseRuns: {
27
- id: 'components.SyllabusAsideList.noOtherCourseRuns',
28
- description:
29
- 'Message displayed on syllabus when there are no other course runs to show than the only one opened',
30
- defaultMessage: 'No other course runs',
31
- },
32
21
  toBeScheduled: {
33
22
  id: 'components.SyllabusAsideList.toBeScheduled',
34
23
  description: 'Message displayed on syllabus when there are course runs to be scheduled',
@@ -108,28 +97,20 @@ export const SyllabusAsideList = ({
108
97
 
109
98
  const showLanguages = CourseRunHelper.IsAllCourseRunsWithSameLanguages(courseRuns);
110
99
 
100
+ // If there are no runs to display at all, don't render anything
101
+ if (openedRuns.length <= 1 && otherRuns.length === 0) {
102
+ return null;
103
+ }
104
+
111
105
  return (
112
106
  <>
113
107
  <h2 className="course-detail__title">
114
- {openedRuns.length === 1 ? (
115
- <FormattedMessage {...messages.otherCourseRuns} />
116
- ) : (
108
+ {openedRuns.length > 1 ? (
117
109
  <FormattedMessage {...messages.courseRunsTitle} />
110
+ ) : (
111
+ <FormattedMessage {...messages.otherCourseRuns} />
118
112
  )}
119
113
  </h2>
120
- {openedRuns.length <= 1 && otherRuns.length === 0 && (
121
- <div className="course-detail__row course-detail__no-runs">
122
- {openedRuns.length === 0 ? (
123
- <p>
124
- <FormattedMessage {...messages.noCourseRuns} />
125
- </p>
126
- ) : (
127
- <p>
128
- <FormattedMessage {...messages.noOtherCourseRuns} />
129
- </p>
130
- )}
131
- </div>
132
- )}
133
114
  {openedRuns.length > 1 && (
134
115
  <div
135
116
  id="courseDetailsRunsOpen"
@@ -34,13 +34,18 @@ const messages = defineMessages({
34
34
  selfPaceRunPeriod: {
35
35
  id: 'components.SyllabusCourseRunCompacted.selfPaceCoursePeriod',
36
36
  description: 'Course date of an opened and self paced course run block',
37
- defaultMessage: 'Available until {endDate}',
37
+ defaultMessage: 'Until {endDate, select, undefined {} other {{endDate}}}',
38
38
  },
39
39
  selfPaceNoEndDate: {
40
40
  id: 'components.SyllabusCourseRunCompacted.selfPaceNoEndDate',
41
41
  description: 'Self paced course run block with no end date',
42
42
  defaultMessage: 'Available',
43
43
  },
44
+ enrollment: {
45
+ id: 'components.SyllabusCourseRun.enrollment',
46
+ description: 'Title of the enrollment dates section of an opened course run block',
47
+ defaultMessage: 'Enrollment',
48
+ },
44
49
  coursePrice: {
45
50
  id: 'components.SyllabusCourseRunCompacted.coursePrice',
46
51
  description: 'Title of the course enrollment price section of an opened course run block',
@@ -105,6 +110,7 @@ const OpenedSelfPacedCourseRun = ({
105
110
  let enrollmentDiscountedPrice = '';
106
111
  let certificatePrice = '';
107
112
  let certificateDiscountedPrice = '';
113
+ const enrollmentEnd = courseRun.enrollment_end ? formatDate(courseRun.enrollment_end) : '...';
108
114
 
109
115
  if (courseRun.offer) {
110
116
  const offer = courseRun.offer.toUpperCase().replaceAll(' ', '_');
@@ -157,23 +163,41 @@ const OpenedSelfPacedCourseRun = ({
157
163
  <>
158
164
  {courseRun.title && <h3>{StringHelper.capitalizeFirst(courseRun.title)}</h3>}
159
165
  <dl>
160
- {!showLanguages && (
161
- <dt>
162
- <FormattedMessage {...messages.course} />
163
- </dt>
166
+ {hasEndDate ? (
167
+ <>
168
+ <dt>
169
+ <FormattedMessage {...messages.enrollment} />
170
+ </dt>
171
+ <dd>
172
+ <FormattedMessage
173
+ {...messages.selfPaceRunPeriod}
174
+ values={{
175
+ endDate: enrollmentEnd,
176
+ }}
177
+ />
178
+ </dd>
179
+ <dt>
180
+ <FormattedMessage {...messages.course} />
181
+ </dt>
182
+ <dd>
183
+ <FormattedMessage
184
+ {...messages.selfPaceRunPeriod}
185
+ values={{
186
+ endDate: end,
187
+ }}
188
+ />
189
+ </dd>
190
+ </>
191
+ ) : (
192
+ <>
193
+ <dt>
194
+ <FormattedMessage {...messages.enrollment} />
195
+ </dt>
196
+ <dd>
197
+ <FormattedMessage {...messages.selfPaceNoEndDate} />
198
+ </dd>
199
+ </>
164
200
  )}
165
- <dd>
166
- {hasEndDate ? (
167
- <FormattedMessage
168
- {...messages.selfPaceRunPeriod}
169
- values={{
170
- endDate: end,
171
- }}
172
- />
173
- ) : (
174
- <FormattedMessage {...messages.selfPaceNoEndDate} />
175
- )}
176
- </dd>
177
201
  {!showLanguages && (
178
202
  <>
179
203
  <dt>
@@ -172,7 +172,7 @@ describe('<SyllabusCourseRunsList/>', () => {
172
172
  });
173
173
  const runContainer = heading.parentNode! as HTMLElement;
174
174
  const courseDatesText = courseRun.end
175
- ? `Available until ${intl.formatDate(new Date(courseRun.end), DEFAULT_DATE_FORMAT)}`
175
+ ? `Until ${intl.formatDate(new Date(courseRun.end), DEFAULT_DATE_FORMAT)}`
176
176
  : `Available`;
177
177
 
178
178
  const courseDatesContainer = getByText(runContainer, courseDatesText);
@@ -221,7 +221,7 @@ describe('<SyllabusCourseRunsList/>', () => {
221
221
  const expectEmptyPortalContainer = () => {
222
222
  // This way of testing is a bit hard but we are SURE that there is no other content. This way
223
223
  // we are also testing the absence of other elements.
224
- expect(getPortalContainer().textContent).toEqual('Other course runsNo other course runs');
224
+ expect(getPortalContainer().textContent).toContain('Other course runs');
225
225
  };
226
226
 
227
227
  it('has no opened course run', async () => {
@@ -390,10 +390,13 @@ describe('<SyllabusCourseRunsList/>', () => {
390
390
  const courseRun = CourseRunFactoryFromPriority(Priority.ONGOING_OPEN)({
391
391
  resource_link: resourceLink,
392
392
  }).one();
393
+ const archivedCourseRun = CourseRunFactoryFromPriority(Priority.ARCHIVED_CLOSED)({
394
+ resource_link: resourceLink,
395
+ }).one();
393
396
 
394
397
  render(
395
398
  <SyllabusCourseRunsList
396
- courseRuns={[courseRun]}
399
+ courseRuns={[courseRun, archivedCourseRun]}
397
400
  course={course}
398
401
  maxArchivedCourseRuns={MAX_ARCHIVED_COURSE_RUNS}
399
402
  />,
@@ -412,12 +415,42 @@ describe('<SyllabusCourseRunsList/>', () => {
412
415
  expectEmptyPortalContainer();
413
416
  });
414
417
 
418
+ it('has only one opened product', async () => {
419
+ const course = PacedCourseFactory().one();
420
+ const offering = OfferingFactory().one();
421
+ const resourceLink = `https://joanie.endpoint/api/v1.0/courses/${course.code}/products/${offering.product.id}/`;
422
+ fetchMock.get(resourceLink, offering);
423
+
424
+ const courseRun = CourseRunFactoryFromPriority(Priority.ONGOING_OPEN)({
425
+ resource_link: resourceLink,
426
+ }).one();
427
+
428
+ render(
429
+ <SyllabusCourseRunsList
430
+ courseRuns={[courseRun]}
431
+ course={course}
432
+ maxArchivedCourseRuns={MAX_ARCHIVED_COURSE_RUNS}
433
+ />,
434
+ {
435
+ queryOptions: { client: createTestQueryClient({ user: null }) },
436
+ },
437
+ );
438
+
439
+ // Header.
440
+ expect(getHeaderContainer().querySelectorAll('.course-detail__run-descriptions').length).toBe(
441
+ 1,
442
+ );
443
+ await expectCourseProduct(getHeaderContainer(), offering);
444
+ });
445
+
415
446
  it('renders a specific title in portal when there is one opened course run', () => {
416
447
  const course = PacedCourseFactory().one();
448
+ const ongoingOpenCourseRun = CourseRunFactoryFromPriority(Priority.ONGOING_OPEN)().one();
449
+ const archivedCourseRun = CourseRunFactoryFromPriority(Priority.ARCHIVED_CLOSED)().one();
417
450
 
418
451
  render(
419
452
  <SyllabusCourseRunsList
420
- courseRuns={[CourseRunFactoryFromPriority(Priority.ONGOING_OPEN)().one()]}
453
+ courseRuns={[ongoingOpenCourseRun, archivedCourseRun]}
421
454
  course={course}
422
455
  maxArchivedCourseRuns={MAX_ARCHIVED_COURSE_RUNS}
423
456
  />,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "richie-education",
3
- "version": "3.3.1-dev12",
3
+ "version": "3.3.1-dev13",
4
4
  "description": "A CMS to build learning portals for Open Education",
5
5
  "main": "sandbox/manage.py",
6
6
  "scripts": {