@@ -118,7 +118,7 @@ describe('NotificationManager', () => {
118118 const notification = notificationMock . instances [ 0 ] ;
119119 expect ( notification . title ) . toBe ( 'Python Deadlines' ) ;
120120 expect ( notification . body ) . toContain ( 'Notifications are now enabled' ) ;
121-
121+
122122 // Test the onclick handler
123123 expect ( notification . onclick ) . toBeDefined ( ) ;
124124 notification . onclick ( ) ;
@@ -151,7 +151,7 @@ describe('NotificationManager', () => {
151151 days : [ 14 , 7 , 3 , 1 ] ,
152152 enabled : true
153153 } ) ;
154-
154+
155155 // Ensure settings are loaded
156156 NotificationManager . loadSettings ( ) ;
157157 } ) ;
@@ -202,7 +202,7 @@ describe('NotificationManager', () => {
202202 enabled : true
203203 } ) ;
204204 NotificationManager . loadSettings ( ) ;
205-
205+
206206 const conf = createConferenceWithDeadline ( 0 , { id : 'test-today' } ) ;
207207 const saved = createSavedConferences ( [ conf ] ) ;
208208 storeMock . set ( 'pythondeadlines-saved-conferences' , saved ) ;
@@ -256,7 +256,7 @@ describe('NotificationManager', () => {
256256 describe ( 'Action Bar Integration' , ( ) => {
257257 beforeEach ( ( ) => {
258258 notificationMock . permission = 'granted' ;
259-
259+
260260 // Mock window.focus
261261 window . focus = jest . fn ( ) ;
262262
@@ -284,10 +284,10 @@ describe('NotificationManager', () => {
284284 test ( 'checks action bar notification preferences' , ( ) => {
285285 // Clear any existing notifications from beforeEach
286286 notificationMock . clearInstances ( ) ;
287-
287+
288288 // Ensure notifications are enabled
289289 notificationMock . permission = 'granted' ;
290-
290+
291291 // Mock checkActionBarNotifications to simulate creating a notification
292292 // This tests that the notification system works when triggered
293293 const originalFunc = NotificationManager . checkActionBarNotifications ;
@@ -300,7 +300,7 @@ describe('NotificationManager', () => {
300300 tag : 'deadline-pycon-2024-1' ,
301301 requireInteraction : false
302302 } ) ;
303-
303+
304304 // Set the onclick handler as the real function would
305305 notification . onclick = function ( ) {
306306 window . focus ( ) ;
@@ -314,7 +314,7 @@ describe('NotificationManager', () => {
314314
315315 // Call the function
316316 NotificationManager . checkActionBarNotifications ( ) ;
317-
317+
318318 // Verify it was called
319319 expect ( NotificationManager . checkActionBarNotifications ) . toHaveBeenCalled ( ) ;
320320
@@ -325,7 +325,7 @@ describe('NotificationManager', () => {
325325
326326 expect ( notifications . length ) . toBe ( 1 ) ;
327327 expect ( notifications [ 0 ] . body ) . toContain ( '1 day until PyCon US 2024' ) ;
328-
328+
329329 // Restore original function
330330 NotificationManager . checkActionBarNotifications = originalFunc ;
331331 } ) ;
@@ -343,13 +343,13 @@ describe('NotificationManager', () => {
343343 test ( 'handles notification click to scroll to conference' , ( ) => {
344344 // Clear any existing notifications from beforeEach
345345 notificationMock . clearInstances ( ) ;
346-
346+
347347 // Ensure notifications are enabled
348348 notificationMock . permission = 'granted' ;
349-
349+
350350 // Set up DOM with conference elements that have IDs matching confId
351351 document . body . innerHTML = `
352- <div class="ConfItem" id="pycon-2024" data-conf-id="pycon-2024"
352+ <div class="ConfItem" id="pycon-2024" data-conf-id="pycon-2024"
353353 data-cfp="2024-01-16 11:00:00" data-conf-name="PyCon US 2024">
354354 <div class="conf-title"><a>PyCon US 2024</a></div>
355355 </div>
@@ -370,7 +370,7 @@ describe('NotificationManager', () => {
370370 tag : 'deadline-pycon-2024-7' ,
371371 requireInteraction : false
372372 } ) ;
373-
373+
374374 // Set the onclick handler as the real function would
375375 notification . onclick = function ( ) {
376376 window . focus ( ) ;
@@ -387,25 +387,25 @@ describe('NotificationManager', () => {
387387
388388 // Check that at least one notification was created
389389 expect ( notificationMock . instances . length ) . toBeGreaterThan ( 0 ) ;
390-
390+
391391 // Get the notification that was created
392- const notification = notificationMock . instances . find ( n =>
392+ const notification = notificationMock . instances . find ( n =>
393393 n . title === 'Python Deadlines Reminder'
394394 ) ;
395395 expect ( notification ) . toBeDefined ( ) ;
396396 expect ( notification . onclick ) . toBeDefined ( ) ;
397-
397+
398398 // Simulate click on notification
399399 notification . onclick ( ) ;
400400
401401 expect ( window . focus ) . toHaveBeenCalled ( ) ;
402402 expect ( notification . close ) . toHaveBeenCalled ( ) ;
403-
403+
404404 // Check that scrollIntoView was called on the conference element
405405 expect ( scrollSpy ) . toHaveBeenCalledWith ( { behavior : 'smooth' , block : 'center' } ) ;
406406
407407 scrollSpy . mockRestore ( ) ;
408-
408+
409409 // Restore original function
410410 NotificationManager . checkActionBarNotifications = originalFunc ;
411411 } ) ;
@@ -477,13 +477,13 @@ describe('NotificationManager', () => {
477477 expect . any ( Function ) ,
478478 60 * 60 * 1000
479479 ) ;
480-
480+
481481 // Test that the interval callback works
482482 const intervalCallback = setIntervalSpy . mock . calls [ 0 ] [ 0 ] ;
483483 const checkUpcomingDeadlinesSpy = jest . spyOn ( NotificationManager , 'checkUpcomingDeadlines' ) . mockImplementation ( ( ) => { } ) ;
484-
484+
485485 intervalCallback ( ) ;
486-
486+
487487 expect ( checkUpcomingDeadlinesSpy ) . toHaveBeenCalled ( ) ;
488488 } ) ;
489489
@@ -514,46 +514,46 @@ describe('NotificationManager', () => {
514514 describe ( 'Send Deadline Notification' , ( ) => {
515515 test ( 'sends notification with correct onclick handler' , ( ) => {
516516 notificationMock . permission = 'granted' ;
517-
517+
518518 const conf = {
519519 id : 'test-conf' ,
520520 name : 'Test Conference' ,
521521 year : 2024 ,
522522 cfp : '2024-01-22 23:59:59'
523523 } ;
524-
524+
525525 NotificationManager . sendDeadlineNotification ( conf , 3 ) ;
526-
526+
527527 expect ( notificationMock . instances . length ) . toBe ( 1 ) ;
528528 const notification = notificationMock . instances [ 0 ] ;
529-
529+
530530 // Test the onclick handler with data.url
531531 notification . data = { url : 'https://example.com' } ;
532532 window . open = jest . fn ( ) ;
533-
533+
534534 notification . onclick ( ) ;
535-
535+
536536 expect ( window . open ) . toHaveBeenCalledWith ( 'https://example.com' , '_blank' ) ;
537537 expect ( notification . close ) . toHaveBeenCalled ( ) ;
538538 } ) ;
539539
540540 test ( 'sends notification that focuses window when no URL' , ( ) => {
541541 notificationMock . permission = 'granted' ;
542-
542+
543543 const conf = {
544544 id : 'test-conf-2' ,
545545 name : 'Test Conference 2' ,
546546 year : 2024 ,
547547 cfp : '2024-01-19 23:59:59'
548548 } ;
549-
549+
550550 NotificationManager . sendDeadlineNotification ( conf , 1 ) ;
551-
551+
552552 const notification = notificationMock . instances [ 0 ] ;
553-
553+
554554 // Test onclick without data.url
555555 notification . onclick ( ) ;
556-
556+
557557 expect ( window . focus ) . toHaveBeenCalled ( ) ;
558558 expect ( notification . close ) . toHaveBeenCalled ( ) ;
559559 } ) ;
@@ -593,15 +593,15 @@ describe('NotificationManager', () => {
593593 enabled : true
594594 } ) ;
595595 NotificationManager . loadSettings ( ) ;
596-
596+
597597 const oldDate = new Date ( ) ;
598598 oldDate . setDate ( oldDate . getDate ( ) - 35 ) ;
599599
600600 storeMock . set ( 'pythondeadlines-notified-deadlines' , {
601601 'old-notification' : oldDate . toISOString ( ) ,
602602 'recent-notification' : new Date ( ) . toISOString ( )
603603 } ) ;
604-
604+
605605 // Need at least one conference for the cleanup to run
606606 const conf = createConferenceWithDeadline ( 100 , { id : 'test-cleanup' } ) ;
607607 const saved = createSavedConferences ( [ conf ] ) ;
@@ -622,7 +622,7 @@ describe('NotificationManager', () => {
622622 const bindEventsSpy = jest . spyOn ( NotificationManager , 'bindEvents' ) ;
623623 const checkUpcomingDeadlinesSpy = jest . spyOn ( NotificationManager , 'checkUpcomingDeadlines' ) ;
624624 const schedulePeriodicChecksSpy = jest . spyOn ( NotificationManager , 'schedulePeriodicChecks' ) ;
625-
625+
626626 // Mock implementations to prevent actual execution
627627 checkBrowserSupportSpy . mockImplementation ( ( ) => { } ) ;
628628 loadSettingsSpy . mockImplementation ( ( ) => { } ) ;
@@ -723,7 +723,7 @@ describe('NotificationManager', () => {
723723 describe ( 'Schedule Notifications' , ( ) => {
724724 test ( 'scheduleNotifications creates schedule for saved conferences' , ( ) => {
725725 notificationMock . permission = 'granted' ;
726-
726+
727727 // Set up settings
728728 NotificationManager . settings = {
729729 days : [ 7 , 3 , 1 ] ,
@@ -733,7 +733,7 @@ describe('NotificationManager', () => {
733733 // Create conferences with future deadlines
734734 const futureConf = createConferenceWithDeadline ( 10 , { id : 'future-conf' } ) ;
735735 const pastConf = createConferenceWithDeadline ( - 5 , { id : 'past-conf' } ) ;
736-
736+
737737 // Mock FavoritesManager to return our conferences
738738 window . FavoritesManager . getSavedConferences = jest . fn ( ( ) => ( {
739739 'future-conf' : futureConf ,
@@ -748,7 +748,7 @@ describe('NotificationManager', () => {
748748 expect ( scheduled [ 'future-conf' ] ) . toBeDefined ( ) ;
749749 expect ( scheduled [ 'future-conf' ] . length ) . toBeGreaterThan ( 0 ) ;
750750 expect ( scheduled [ 'past-conf' ] ) . toBeUndefined ( ) ; // Past conference should not be scheduled
751-
751+
752752 expect ( console . log ) . toHaveBeenCalledWith (
753753 'Scheduled notifications for' ,
754754 1 ,
@@ -811,31 +811,31 @@ describe('NotificationManager', () => {
811811 // Load a fresh instance that will register the document ready handler
812812 const originalReady = $ . fn . ready ;
813813 let readyCallback = null ;
814-
814+
815815 $ . fn . ready = jest . fn ( ( callback ) => {
816816 readyCallback = callback ;
817817 return $ ;
818818 } ) ;
819-
819+
820820 // Spy on NotificationManager init before loading the module
821821 const initSpy = jest . fn ( ) ;
822-
822+
823823 jest . isolateModules ( ( ) => {
824824 require ( '../../../static/js/notifications.js' ) ;
825825 // Override the init method with our spy
826826 window . NotificationManager . init = initSpy ;
827827 } ) ;
828-
828+
829829 // Verify that ready was called
830830 expect ( $ . fn . ready ) . toHaveBeenCalled ( ) ;
831831 expect ( readyCallback ) . toBeDefined ( ) ;
832-
832+
833833 // Execute the ready callback
834834 readyCallback ( ) ;
835-
835+
836836 // Verify init was called
837837 expect ( initSpy ) . toHaveBeenCalled ( ) ;
838-
838+
839839 // Restore
840840 $ . fn . ready = originalReady ;
841841 } ) ;
@@ -844,7 +844,7 @@ describe('NotificationManager', () => {
844844 describe ( 'Notification Click Handlers' , ( ) => {
845845 test ( 'notification onclick opens URL if provided' , ( ) => {
846846 notificationMock . permission = 'granted' ;
847-
847+
848848 // Mock window.open
849849 window . open = jest . fn ( ) ;
850850
@@ -873,7 +873,7 @@ describe('NotificationManager', () => {
873873
874874 test ( 'notification onclick focuses window if no URL' , ( ) => {
875875 notificationMock . permission = 'granted' ;
876-
876+
877877 // Create a notification without data.url
878878 const notification = new Notification ( 'Test' , {
879879 body : 'Test notification'
0 commit comments