@@ -84,7 +84,13 @@ func TestAlertMonitor_ConsecutiveFailures_MaxFailures(t *testing.T) {
8484 consecutiveFailureCount ++
8585 cf := cfAlert .Data .ConsecutiveFailures
8686 require .Contains (t , []int {10 , 14 , 18 , 20 }, cf .Current , "Alert should be sent at 50%, 66%, 90%, and 100% thresholds" )
87- require .Equal (t , dest , cfAlert .Data .Destination )
87+ require .Equal (t , dest .ID , cfAlert .Data .Destination .ID )
88+ require .Equal (t , dest .TenantID , cfAlert .Data .Destination .TenantID )
89+ if cf .Threshold == 100 {
90+ require .NotNil (t , cfAlert .Data .Destination .DisabledAt , "Destination should have DisabledAt at threshold 100" )
91+ } else {
92+ require .Nil (t , cfAlert .Data .Destination .DisabledAt , "Destination should not have DisabledAt below threshold 100" )
93+ }
8894 require .Equal (t , "alert.destination.consecutive_failure" , cfAlert .Topic )
8995 require .Equal (t , "attempt_1" , cfAlert .Data .Attempt .ID )
9096 require .Equal (t , 20 , cf .Max )
@@ -357,3 +363,68 @@ func TestAlertMonitor_SendsDestinationDisabledAlert(t *testing.T) {
357363 assert .Equal (t , event .ID , destinationDisabledAlert .Data .Event .ID , "Event ID should match" )
358364 assert .Equal (t , event .Topic , destinationDisabledAlert .Data .Event .Topic , "Event Topic should match" )
359365}
366+
367+ func TestAlertMonitor_ConsecutiveFailureAlert_ReflectsDisabledDestination (t * testing.T ) {
368+ // Tests that the consecutive failure alert at threshold 100 includes
369+ // the destination with DisabledAt set, reflecting the post-disable state.
370+ t .Parallel ()
371+ ctx := context .Background ()
372+ logger := testutil .CreateTestLogger (t )
373+ redisClient := testutil .CreateTestRedisClient (t )
374+ notifier := & mockAlertNotifier {}
375+ notifier .On ("Notify" , mock .Anything , mock .Anything ).Return (nil )
376+
377+ disabledAt := time .Now ()
378+ modelsDest := testutil .DestinationFactory .Any (
379+ testutil .DestinationFactory .WithID ("dest_reflect" ),
380+ testutil .DestinationFactory .WithTenantID ("tenant_reflect" ),
381+ )
382+ modelsDest .DisabledAt = & disabledAt
383+ disabler := & mockDestinationDisabler {}
384+ disabler .On ("DisableDestination" , mock .Anything , mock .Anything , mock .Anything ).Return (modelsDest , nil )
385+
386+ autoDisableCount := 5
387+ monitor := alert .NewAlertMonitor (
388+ logger ,
389+ redisClient ,
390+ alert .WithNotifier (notifier ),
391+ alert .WithDisabler (disabler ),
392+ alert .WithAutoDisableFailureCount (autoDisableCount ),
393+ alert .WithAlertThresholds ([]int {100 }),
394+ )
395+
396+ dest := & alert.AlertDestination {ID : "dest_reflect" , TenantID : "tenant_reflect" }
397+ event := testutil .EventFactory .AnyPointer (
398+ testutil .EventFactory .WithID ("event_reflect" ),
399+ )
400+ attempt := alert.DeliveryAttempt {
401+ Event : event ,
402+ Destination : dest ,
403+ Attempt : testutil .AttemptFactory .AnyPointer (
404+ testutil .AttemptFactory .WithID ("attempt_reflect" ),
405+ testutil .AttemptFactory .WithStatus ("failed" ),
406+ testutil .AttemptFactory .WithCode ("500" ),
407+ ),
408+ }
409+
410+ for i := 1 ; i <= autoDisableCount ; i ++ {
411+ require .NoError (t , monitor .HandleAttempt (ctx , attempt ))
412+ }
413+
414+ // Find the consecutive failure alert at threshold 100
415+ var found bool
416+ for _ , call := range notifier .Calls {
417+ if call .Method == "Notify" {
418+ if cfAlert , ok := call .Arguments .Get (1 ).(alert.ConsecutiveFailureAlert ); ok {
419+ if cfAlert .Data .ConsecutiveFailures .Threshold == 100 {
420+ found = true
421+ // The destination in the alert should reflect the disabled state
422+ require .NotNil (t , cfAlert .Data .Destination .DisabledAt , "Destination in consecutive failure alert at threshold 100 should have DisabledAt set" )
423+ assert .Equal (t , disabledAt , * cfAlert .Data .Destination .DisabledAt , "DisabledAt should match" )
424+ break
425+ }
426+ }
427+ }
428+ }
429+ require .True (t , found , "Should have found a consecutive failure alert at threshold 100" )
430+ }
0 commit comments