@@ -344,4 +344,71 @@ module('Unit | Flash | object', function (hooks) {
344344
345345 assert . notOk ( flash . timerTaskInstance , 'no timer when timeout is undefined' ) ;
346346 } ) ;
347+
348+ test ( 'custom properties starting with "on" are preserved' , function ( assert ) {
349+ interface CustomFields extends Record < string , unknown > {
350+ onAction : ( ) => void ;
351+ onRetry : ( ) => void ;
352+ }
353+
354+ let actionCalled = false ;
355+ let retryCalled = false ;
356+
357+ const flash = new FlashMessage < CustomFields > ( {
358+ message : 'test' ,
359+ sticky : true ,
360+ onAction : ( ) => {
361+ actionCalled = true ;
362+ } ,
363+ onRetry : ( ) => {
364+ retryCalled = true ;
365+ } ,
366+ } ) ;
367+
368+ const typedFlash = flash as FlashMessage < CustomFields > & CustomFields ;
369+
370+ assert . strictEqual (
371+ typeof typedFlash . onAction ,
372+ 'function' ,
373+ 'onAction is preserved on the flash object' ,
374+ ) ;
375+ assert . strictEqual (
376+ typeof typedFlash . onRetry ,
377+ 'function' ,
378+ 'onRetry is preserved on the flash object' ,
379+ ) ;
380+
381+ typedFlash . onAction ( ) ;
382+ typedFlash . onRetry ( ) ;
383+
384+ assert . true ( actionCalled , 'onAction callback is callable' ) ;
385+ assert . true ( retryCalled , 'onRetry callback is callable' ) ;
386+ } ) ;
387+
388+ test ( 'internal callbacks are not duplicated as custom properties' , function ( assert ) {
389+ let destroyCallCount = 0 ;
390+
391+ const flash = new FlashMessage ( {
392+ message : 'test' ,
393+ sticky : true ,
394+ onDestroy : ( ) => {
395+ destroyCallCount ++ ;
396+ } ,
397+ } ) ;
398+
399+ // onDestroy should be set as the class property, not duplicated
400+ assert . strictEqual (
401+ typeof flash . onDestroy ,
402+ 'function' ,
403+ 'onDestroy is set as class callback' ,
404+ ) ;
405+
406+ // Verify the callback works
407+ flash . onDestroy ?.( ) ;
408+ assert . strictEqual (
409+ destroyCallCount ,
410+ 1 ,
411+ 'onDestroy callback works correctly' ,
412+ ) ;
413+ } ) ;
347414} ) ;
0 commit comments