1
- import datetime
2
-
3
1
# from unittest import skip
4
2
import logging
3
+ import zoneinfo
4
+ from datetime import datetime
5
5
from pathlib import Path
6
+ from unittest .mock import patch
6
7
8
+ from dateutil .relativedelta import relativedelta
7
9
from django .test import override_settings
8
10
from django .test .client import Client
9
11
from django .urls import reverse
@@ -777,13 +779,20 @@ def test_import_0_reimport_1_active_not_verified(self):
777
779
# - active findings count should be 4
778
780
# - total findings count should be 5
779
781
# - zap1 active, zap4 inactive
780
- def test_import_0_reimport_1_active_verified_reimport_0_active_verified (self ):
782
+ # - zap1 is reactivated but should not have a new sla start date and expiration date
783
+ def test_import_0_reimport_1_active_verified_reimport_0_active_verified_sla_no_restart (self ):
781
784
logger .debug ("reimporting updated zap xml report, 1 new finding and 1 no longer present, verified=True and then 0 again" )
782
785
783
786
import0 = self .import_scan_with_params (self .zap_sample0_filename )
784
787
785
788
test_id = import0 ["test" ]
786
789
findings = self .get_test_findings_api (test_id )
790
+
791
+ for finding in findings ["results" ]:
792
+ if "Zap1" in finding ["title" ]:
793
+ zap1_initial_sla_start_date = finding ["sla_start_date" ]
794
+ zap1_initial_sla_expiration_date = finding ["sla_expiration_date" ]
795
+
787
796
self .log_finding_summary_json_api (findings )
788
797
789
798
self .db_finding_count ()
@@ -820,6 +829,8 @@ def test_import_0_reimport_1_active_verified_reimport_0_active_verified(self):
820
829
for finding in findings ["results" ]:
821
830
if "Zap1" in finding ["title" ]:
822
831
self .assertTrue (finding ["active" ])
832
+ self .assertEqual (finding ["sla_start_date" ], zap1_initial_sla_start_date )
833
+ self .assertEqual (finding ["sla_expiration_date" ], zap1_initial_sla_expiration_date )
823
834
zap1_ok = True
824
835
if "Zap4" in finding ["title" ]:
825
836
self .assertFalse (finding ["active" ])
@@ -845,6 +856,90 @@ def test_import_0_reimport_1_active_verified_reimport_0_active_verified(self):
845
856
# zap4 was created and then closed -> only 1 note
846
857
self .assertEqual (notes_count_before + 2 + 1 , self .db_notes_count ())
847
858
859
+ # import 0 and then reimport 1 with zap4 as extra finding, zap1 closed and then reimport 0 again
860
+ # - active findings count should be 4
861
+ # - total findings count should be 5
862
+ # - zap1 active, zap4 inactive
863
+ # - zap1 is reactivated and should have a new sla start date and expiration date since we enabled that flag in the test case
864
+ @patch ("django.utils.timezone.now" )
865
+ def test_import_0_reimport_1_active_verified_reimport_0_active_verified_sla_restart (self , mock_now ):
866
+ fake_now = datetime (2025 , 7 , 1 , tzinfo = zoneinfo .ZoneInfo ("UTC" ))
867
+ mock_now .return_value = fake_now
868
+ logger .debug ("reimporting updated zap xml report, 1 new finding and 1 no longer present, verified=True and then 0 again" )
869
+
870
+ import0 = self .import_scan_with_params (self .zap_sample0_filename )
871
+
872
+ test_id = import0 ["test" ]
873
+ findings = self .get_test_findings_api (test_id )
874
+
875
+ for finding in findings ["results" ]:
876
+ if "Zap1" in finding ["title" ]:
877
+ finding ["sla_start_date" ]
878
+ finding ["sla_expiration_date" ]
879
+ zap1 = Finding .objects .get (id = finding ["id" ])
880
+ sla_configuration = zap1 .get_sla_configuration ()
881
+ sla_configuration .restart_sla_on_reactivation = True
882
+ sla_configuration .save ()
883
+
884
+ self .log_finding_summary_json_api (findings )
885
+
886
+ self .db_finding_count ()
887
+ endpoint_count_before = self .db_endpoint_count ()
888
+ endpoint_status_count_before_active = self .db_endpoint_status_count (mitigated = False )
889
+ endpoint_status_count_before_mitigated = self .db_endpoint_status_count (mitigated = True )
890
+ notes_count_before = self .db_notes_count ()
891
+
892
+ reimport1 = self .reimport_scan_with_params (test_id , self .zap_sample1_filename )
893
+
894
+ # zap1 should be closed 2 endpoint statuses less, but 2 extra for zap4
895
+ self .assertEqual (endpoint_status_count_before_active - 3 + 2 , self .db_endpoint_status_count (mitigated = False ))
896
+ self .assertEqual (endpoint_status_count_before_mitigated + 2 , self .db_endpoint_status_count (mitigated = True ))
897
+
898
+ endpoint_status_count_before_active = self .db_endpoint_status_count (mitigated = False )
899
+ endpoint_status_count_before_mitigated = self .db_endpoint_status_count (mitigated = True )
900
+
901
+ with assertTestImportModelsCreated (self , reimports = 1 , affected_findings = 2 , closed = 1 , reactivated = 1 , untouched = 3 ):
902
+ self .reimport_scan_with_params (test_id , self .zap_sample0_filename )
903
+
904
+ test_id = reimport1 ["test" ]
905
+ self .assertEqual (test_id , test_id )
906
+
907
+ self .get_test_api (test_id )
908
+ findings = self .get_test_findings_api (test_id )
909
+ self .log_finding_summary_json_api (findings )
910
+
911
+ # active findings must be equal to those in both reports
912
+ findings = self .get_test_findings_api (test_id )
913
+ self .assert_finding_count_json (4 + 1 , findings )
914
+
915
+ for finding in findings ["results" ]:
916
+ if "Zap1" in finding ["title" ]:
917
+ self .assertTrue (finding ["active" ])
918
+ self .assertEqual (finding ["sla_start_date" ], fake_now .date ().isoformat ())
919
+ sla_days = finding ["severity" ].lower ()
920
+ sla_config = Finding .objects .get (id = finding ["id" ]).test .engagement .product .sla_configuration
921
+ sla_expiration_date = fake_now .date () + relativedelta (days = getattr (sla_config , sla_days ))
922
+ self .assertEqual (finding ["sla_expiration_date" ], sla_expiration_date .isoformat ())
923
+ else :
924
+ self .assertIsNone (finding ["sla_start_date" ])
925
+
926
+ # verified findings must be equal to those in report 0
927
+ findings = self .get_test_findings_api (test_id , verified = True )
928
+ self .assert_finding_count_json (0 , findings )
929
+
930
+ findings = self .get_test_findings_api (test_id , verified = False )
931
+ self .assert_finding_count_json (5 , findings )
932
+
933
+ self .assertEqual (endpoint_count_before , self .db_endpoint_count ())
934
+
935
+ # zap4 should be closed again so 2 mitigated eps, zap1 should be open again so 3 active extra
936
+ self .assertEqual (endpoint_status_count_before_active + 3 - 2 , self .db_endpoint_status_count (mitigated = False ))
937
+ self .assertEqual (endpoint_status_count_before_mitigated - 3 + 2 , self .db_endpoint_status_count (mitigated = True ))
938
+
939
+ # zap1 was closed and then opened -> 2 notes
940
+ # zap4 was created and then closed -> only 1 note
941
+ self .assertEqual (notes_count_before + 2 + 1 , self .db_notes_count ())
942
+
848
943
# import 0 and then reimport 2 with an extra endpoint for zap1
849
944
# - extra endpoint should be present in db
850
945
# - reimport doesn't look at endpoints to match against existing findings
@@ -1522,8 +1617,8 @@ def test_import_reimport_vulnerability_ids(self):
1522
1617
engagement = test .engagement ,
1523
1618
test_type = test_type ,
1524
1619
scan_type = self .anchore_grype_scan_type ,
1525
- target_start = datetime .datetime . now (datetime . UTC ),
1526
- target_end = datetime .datetime . now (datetime . UTC ),
1620
+ target_start = datetime .now (timezone . get_current_timezone () ),
1621
+ target_end = datetime .now (timezone . get_current_timezone () ),
1527
1622
)
1528
1623
reimport_test .save ()
1529
1624
0 commit comments