66from robusta .core .reporting import Finding
77from robusta .core .sinks .sink_base import SinkBase
88from robusta .core .sinks .sink_base_params import ActivityParams
9- from robusta .core .sinks .timing import TimeSlice
9+ from robusta .core .sinks .timing import MuteDateInterval , TimeSlice
1010
1111
1212class TestTimeSlice :
@@ -39,6 +39,40 @@ def test_invalid_time(self, time):
3939 TimeSlice ([], [time ], "UTC" )
4040
4141
42+ class TestMuteDateInterval :
43+ def test_unknown_timezone (self ):
44+ with pytest .raises (ValueError ):
45+ MuteDateInterval ("01-01 00:00" , "01-02 00:00" , "Mars/Cydonia" )
46+
47+ @pytest .mark .parametrize (
48+ "start_date,end_date,timezone,expected_muted" ,
49+ [
50+ # 2012-01-01 13:45 UTC - currently muted (within range)
51+ ("01-01 00:00" , "01-01 23:59" , "UTC" , True ),
52+ # Currently muted (multi-day range)
53+ ("12-31 00:00" , "01-02 10:00" , "UTC" , True ),
54+ # Not muted (range in February)
55+ ("02-01 00:00" , "02-28 23:59" , "UTC" , False ),
56+ # Not muted (same day but hours don't match - before current time)
57+ ("01-01 00:00" , "01-01 13:00" , "UTC" , False ),
58+ # Muted (same day, hours match)
59+ ("01-01 13:00" , "01-01 14:00" , "UTC" , True ),
60+ # Year-boundary wrap: Dec 20 to Jan 5 should mute on Jan 1
61+ ("12-20 00:00" , "01-05 23:59" , "UTC" , True ),
62+ # Year-boundary wrap: March to Feb wraps around, Jan 1 IS inside that range
63+ ("03-01 00:00" , "02-15 23:59" , "UTC" , True ),
64+ # Not muted: range is Feb 1 to Feb 28, Jan 1 is outside
65+ ("02-01 00:00" , "02-10 23:59" , "UTC" , False ),
66+ # Timezone test: 2012-01-01 13:45 UTC = 2012-01-01 14:45 CET
67+ ("01-01 14:00" , "01-01 15:00" , "CET" , True ),
68+ ("01-01 15:00" , "01-01 16:00" , "CET" , False ),
69+ ],
70+ )
71+ def test_is_muted_now (self , start_date , end_date , timezone , expected_muted ):
72+ with freeze_time ("2012-01-01 13:45" ): # UTC time
73+ assert MuteDateInterval (start_date , end_date , timezone ).is_muted_now () is expected_muted
74+
75+
4276class _TestSinkBase (SinkBase ):
4377 def write_finding (self , finding : Finding , platform_enabled : bool ):
4478 pass
@@ -50,6 +84,10 @@ def _build_time_slices_from_params(self, params: ActivityParams):
5084 # We'll construct time_slices explicitly below in TestSinkBase.test_accepts
5185 pass
5286
87+ def _build_mute_intervals_from_params (self , params ):
88+ # We'll construct mute_date_intervals explicitly below
89+ pass
90+
5391
5492class TestSinkBase :
5593 @pytest .mark .parametrize (
@@ -63,6 +101,29 @@ def test_accepts(self, days, time_intervals, expected_result):
63101 mock_registry = Mock (get_global_config = lambda : Mock ())
64102 sink = _TestSinkBase (registry = mock_registry , sink_params = Mock ())
65103 sink .time_slices = [TimeSlice (days , time_intervals , "UTC" )]
104+ sink .mute_date_intervals = []
66105 mock_finding = Mock (matches = Mock (return_value = True ))
67106 with freeze_time ("2012-01-01 13:45" ): # this is UTC time
68107 assert sink .accepts (mock_finding ) is expected_result
108+
109+ def test_accepts_muted (self ):
110+ """When a mute interval is active, accepts() should return False."""
111+ mock_registry = Mock (get_global_config = lambda : Mock ())
112+ sink = _TestSinkBase (registry = mock_registry , sink_params = Mock ())
113+ sink .time_slices = [TimeSlice (["sun" ], [("13:30" , "14:00" )], "UTC" )]
114+ sink .mute_date_intervals = [MuteDateInterval ("01-01 00:00" , "01-01 23:59" , "UTC" )]
115+ mock_finding = Mock (matches = Mock (return_value = True ))
116+ with freeze_time ("2012-01-01 13:45" ): # this is UTC time, Sunday
117+ # Would normally be accepted (Sunday 13:45 in 13:30-14:00), but muted
118+ assert sink .accepts (mock_finding ) is False
119+
120+ def test_accepts_not_muted (self ):
121+ """When no mute interval is active, accepts() works normally."""
122+ mock_registry = Mock (get_global_config = lambda : Mock ())
123+ sink = _TestSinkBase (registry = mock_registry , sink_params = Mock ())
124+ sink .time_slices = [TimeSlice (["sun" ], [("13:30" , "14:00" )], "UTC" )]
125+ sink .mute_date_intervals = [MuteDateInterval ("02-01 00:00" , "02-28 23:59" , "UTC" )]
126+ mock_finding = Mock (matches = Mock (return_value = True ))
127+ with freeze_time ("2012-01-01 13:45" ): # this is UTC time, Sunday
128+ # Mute is for February, so should still accept
129+ assert sink .accepts (mock_finding ) is True
0 commit comments