@@ -6,10 +6,29 @@ import { formatRunDate } from "ol-utilities"
66import invariant from "tiny-invariant"
77import user from "@testing-library/user-event"
88import { renderWithTheme } from "../../test-utils"
9+ import { factories } from "api/test-utils"
910
1011// This is a pipe followed by a zero-width space
1112const SEPARATOR = "|"
1213
14+ // Helper function to create a date N days from today
15+ const daysFromToday = ( days : number ) : string => {
16+ const date = new Date ( )
17+ date . setDate ( date . getDate ( ) + days )
18+ return date . toISOString ( )
19+ }
20+
21+ // Helper to format date as "Month DD, YYYY"
22+ const formatTestDate = ( isoDate : string ) : string => {
23+ const date = new Date ( isoDate )
24+ const options : Intl . DateTimeFormatOptions = {
25+ year : "numeric" ,
26+ month : "long" ,
27+ day : "2-digit" ,
28+ }
29+ return date . toLocaleDateString ( "en-US" , options )
30+ }
31+
1332describe ( "Learning resource info section pricing" , ( ) => {
1433 test ( "Free course, no certificate" , ( ) => {
1534 renderWithTheme ( < InfoSection resource = { courses . free . noCertificate } /> )
@@ -118,65 +137,71 @@ describe("Learning resource info section start date", () => {
118137 test ( "Uses best_run_id when available" , ( ) => {
119138 const run = courses . free . dated . runs ?. [ 0 ]
120139 invariant ( run )
140+ const startDate = daysFromToday ( 30 )
141+ const enrollmentStart = daysFromToday ( 15 )
121142 const course = {
122143 ...courses . free . dated ,
123144 best_run_id : 1 ,
124145 runs : [
125146 {
126147 ...run ,
127148 id : 1 ,
128- start_date : "2024-03-15" ,
129- enrollment_start : "2024-03-01" ,
149+ start_date : startDate ,
150+ enrollment_start : enrollmentStart ,
130151 } ,
131152 ] ,
132153 }
133154 renderWithTheme ( < InfoSection resource = { course } /> )
134155
135156 const section = screen . getByTestId ( "drawer-info-items" )
136157 within ( section ) . getByText ( "Starts:" )
137- within ( section ) . getByText ( "March 15, 2024" )
158+ within ( section ) . getByText ( formatTestDate ( startDate ) )
138159 } )
139160
140- test ( "Falls back to run date when best_run_id is null" , ( ) => {
161+ test ( "Shows run date when best_run_id matches a run" , ( ) => {
162+ const startDate = daysFromToday ( 45 )
163+ const run = factories . learningResources . run ( {
164+ id : 1 ,
165+ start_date : startDate ,
166+ enrollment_start : null ,
167+ } )
141168 const course = {
142169 ...courses . free . dated ,
143- best_run_id : null ,
170+ best_run_id : 1 ,
171+ runs : [ run ] ,
144172 }
145- const run = course . runs ?. [ 0 ]
146- invariant ( run )
147- const runDate = formatRunDate ( run , false )
148- invariant ( runDate )
149173 renderWithTheme ( < InfoSection resource = { course } /> )
150174
151175 const section = screen . getByTestId ( "drawer-info-items" )
152176 within ( section ) . getByText ( "Starts:" )
153- within ( section ) . getByText ( runDate )
154- expect ( within ( section ) . queryByText ( "March 15, 2024" ) ) . toBeNull ( )
177+ within ( section ) . getByText ( formatTestDate ( startDate ) )
155178 } )
156179
157180 test ( "Uses enrollment_start when it is later than start_date" , ( ) => {
158181 const run = courses . free . dated . runs ?. [ 0 ]
159182 invariant ( run )
183+ const startDate = daysFromToday ( 30 )
184+ const enrollmentStart = daysFromToday ( 40 ) // Later than start_date
160185 const course = {
161186 ...courses . free . dated ,
162187 best_run_id : 1 ,
163188 runs : [
164189 {
165190 ...run ,
166191 id : 1 ,
167- start_date : "2024-03-01" ,
168- enrollment_start : "2024-03-15" ,
192+ start_date : startDate ,
193+ enrollment_start : enrollmentStart ,
169194 } ,
170195 ] ,
171196 }
172197 renderWithTheme ( < InfoSection resource = { course } /> )
173198
174199 const section = screen . getByTestId ( "drawer-info-items" )
175200 within ( section ) . getByText ( "Starts:" )
176- within ( section ) . getByText ( "March 15, 2024" )
201+ within ( section ) . getByText ( formatTestDate ( enrollmentStart ) )
177202 } )
178203
179- test ( "Falls back to run date when best_run_id does not match any run" , ( ) => {
204+ test ( "Falls back to null when best_run_id does not match any run" , ( ) => {
180205 const course = {
181206 ...courses . free . dated ,
182207 best_run_id : 999 ,
@@ -192,34 +217,73 @@ describe("Learning resource info section start date", () => {
192217 within ( section ) . getByText ( runDate )
193218 } )
194219
195- test ( "Falls back to run date when best run has no dates " , ( ) => {
220+ test ( "Shows today's date when best run start date is in the past " , ( ) => {
196221 const run = courses . free . dated . runs ?. [ 0 ]
197222 invariant ( run )
223+ const pastStartDate = daysFromToday ( - 30 ) // 30 days ago
224+ const pastEnrollmentStart = daysFromToday ( - 45 ) // 45 days ago
225+ const todayDate = new Date ( ) . toISOString ( )
198226 const course = {
199227 ...courses . free . dated ,
200228 best_run_id : 1 ,
229+ runs : [
230+ {
231+ ...run ,
232+ id : 1 ,
233+ start_date : pastStartDate ,
234+ enrollment_start : pastEnrollmentStart ,
235+ } ,
236+ ] ,
237+ }
238+ renderWithTheme ( < InfoSection resource = { course } /> )
239+
240+ const section = screen . getByTestId ( "drawer-info-items" )
241+ within ( section ) . getByText ( "Starts:" )
242+ within ( section ) . getByText ( formatTestDate ( todayDate ) )
243+ } )
244+
245+ test ( "Shows no start date when best_run_id is null" , ( ) => {
246+ const run = courses . free . dated . runs ?. [ 0 ]
247+ invariant ( run )
248+ const course = {
249+ ...courses . free . dated ,
250+ best_run_id : null ,
201251 runs : [
202252 {
203253 ...run ,
204254 id : 1 ,
205255 start_date : null ,
206256 enrollment_start : null ,
207257 } ,
258+ ] ,
259+ }
260+ renderWithTheme ( < InfoSection resource = { course } /> )
261+
262+ const section = screen . getByTestId ( "drawer-info-items" )
263+ // Should not show a start date section at all when best run is null and no dates exist
264+ expect ( within ( section ) . queryByText ( "Starts:" ) ) . toBeNull ( )
265+ } )
266+
267+ test ( "Shows no start date when best run has null dates" , ( ) => {
268+ const run = courses . free . dated . runs ?. [ 0 ]
269+ invariant ( run )
270+ const course = {
271+ ...courses . free . dated ,
272+ best_run_id : 1 ,
273+ runs : [
208274 {
209275 ...run ,
210- id : 2 ,
211- start_date : "2024-05-01" ,
276+ id : 1 ,
277+ start_date : null ,
212278 enrollment_start : null ,
213279 } ,
214280 ] ,
215281 }
216- const runDate = formatRunDate ( course . runs [ 1 ] , false )
217- invariant ( runDate )
218282 renderWithTheme ( < InfoSection resource = { course } /> )
219283
220284 const section = screen . getByTestId ( "drawer-info-items" )
221- within ( section ) . getByText ( "Starts:" )
222- within ( section ) . getByText ( runDate )
285+ // Should not show a start date section when best run has null dates
286+ expect ( within ( section ) . queryByText ( "Starts:" ) ) . toBeNull ( )
223287 } )
224288
225289 test ( "As taught in date(s)" , ( ) => {
@@ -261,15 +325,17 @@ describe("Learning resource info section start date", () => {
261325 test ( "Multiple run dates with best_run_id uses best_run_id as first date" , ( ) => {
262326 const firstRun = courses . multipleRuns . sameData . runs ?. [ 0 ]
263327 invariant ( firstRun )
328+ const bestRunStartDate = daysFromToday ( 50 )
329+ const bestRunEnrollmentStart = daysFromToday ( 35 )
264330 const course = {
265331 ...courses . multipleRuns . sameData ,
266332 best_run_id : 1 ,
267333 runs : [
268334 {
269335 ...firstRun ,
270336 id : 1 ,
271- start_date : "2024-01-15" ,
272- enrollment_start : "2024-01-01" ,
337+ start_date : bestRunStartDate ,
338+ enrollment_start : bestRunEnrollmentStart ,
273339 } ,
274340 ...( courses . multipleRuns . sameData . runs ?. slice ( 1 ) ?? [ ] ) ,
275341 ] ,
@@ -285,7 +351,7 @@ describe("Learning resource info section start date", () => {
285351 . filter ( ( date ) => date !== null )
286352
287353 // First date should be from best_run_id, second should be original second date
288- const expectedDateText = `January 15, 2024 ${ SEPARATOR } ${ sortedDates ?. [ 1 ] } Show more`
354+ const expectedDateText = `${ formatTestDate ( bestRunStartDate ) } ${ SEPARATOR } ${ sortedDates ?. [ 1 ] } Show more`
289355 renderWithTheme ( < InfoSection resource = { course } /> )
290356
291357 const section = screen . getByTestId ( "drawer-info-items" )
@@ -319,15 +385,17 @@ describe("Learning resource info section start date", () => {
319385 test ( "Anytime courses with best_run_id should not replace first date in 'As taught in' section" , ( ) => {
320386 const firstRun = courses . free . anytime . runs ?. [ 0 ]
321387 invariant ( firstRun )
388+ const bestRunStartDate = daysFromToday ( 25 )
389+ const bestRunEnrollmentStart = daysFromToday ( 10 )
322390 const course = {
323391 ...courses . free . anytime ,
324392 best_run_id : 1 ,
325393 runs : [
326394 {
327395 ...firstRun ,
328396 id : 1 ,
329- start_date : "2024-03-15" ,
330- enrollment_start : "2024-03-01" ,
397+ start_date : bestRunStartDate ,
398+ enrollment_start : bestRunEnrollmentStart ,
331399 } ,
332400 ] ,
333401 }
@@ -341,7 +409,9 @@ describe("Learning resource info section start date", () => {
341409
342410 within ( section ) . getByText ( "As taught in:" )
343411
344- expect ( within ( section ) . queryByText ( "March 15, 2024" ) ) . toBeNull ( )
412+ expect (
413+ within ( section ) . queryByText ( formatTestDate ( bestRunStartDate ) ) ,
414+ ) . toBeNull ( )
345415
346416 const runDates = within ( section ) . getByTestId ( "drawer-run-dates" )
347417 expect ( runDates ) . toBeInTheDocument ( )
0 commit comments