regscale-cli 6.26.0.0__py3-none-any.whl → 6.27.0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of regscale-cli might be problematic. Click here for more details.

Files changed (96) hide show
  1. regscale/_version.py +1 -1
  2. regscale/core/app/application.py +1 -1
  3. regscale/core/app/internal/evidence.py +419 -2
  4. regscale/dev/code_gen.py +24 -20
  5. regscale/integrations/commercial/__init__.py +0 -1
  6. regscale/integrations/commercial/jira.py +367 -126
  7. regscale/integrations/commercial/qualys/__init__.py +7 -8
  8. regscale/integrations/commercial/qualys/scanner.py +8 -3
  9. regscale/integrations/commercial/synqly/assets.py +17 -0
  10. regscale/integrations/commercial/synqly/vulnerabilities.py +45 -28
  11. regscale/integrations/commercial/tenablev2/cis_parsers.py +453 -0
  12. regscale/integrations/commercial/tenablev2/cis_scanner.py +447 -0
  13. regscale/integrations/commercial/tenablev2/commands.py +142 -1
  14. regscale/integrations/commercial/tenablev2/scanner.py +0 -1
  15. regscale/integrations/commercial/tenablev2/stig_parsers.py +113 -57
  16. regscale/integrations/commercial/wizv2/WizDataMixin.py +1 -1
  17. regscale/integrations/commercial/wizv2/click.py +44 -59
  18. regscale/integrations/commercial/wizv2/compliance/__init__.py +15 -0
  19. regscale/integrations/commercial/wizv2/{policy_compliance_helpers.py → compliance/helpers.py} +78 -60
  20. regscale/integrations/commercial/wizv2/compliance_report.py +10 -9
  21. regscale/integrations/commercial/wizv2/core/__init__.py +133 -0
  22. regscale/integrations/commercial/wizv2/{async_client.py → core/client.py} +3 -3
  23. regscale/integrations/commercial/wizv2/{constants.py → core/constants.py} +1 -17
  24. regscale/integrations/commercial/wizv2/core/file_operations.py +237 -0
  25. regscale/integrations/commercial/wizv2/fetchers/__init__.py +11 -0
  26. regscale/integrations/commercial/wizv2/{data_fetcher.py → fetchers/policy_assessment.py} +5 -9
  27. regscale/integrations/commercial/wizv2/issue.py +1 -1
  28. regscale/integrations/commercial/wizv2/models/__init__.py +0 -0
  29. regscale/integrations/commercial/wizv2/parsers/__init__.py +34 -0
  30. regscale/integrations/commercial/wizv2/{parsers.py → parsers/main.py} +1 -1
  31. regscale/integrations/commercial/wizv2/processors/__init__.py +11 -0
  32. regscale/integrations/commercial/wizv2/{finding_processor.py → processors/finding.py} +1 -1
  33. regscale/integrations/commercial/wizv2/reports.py +1 -1
  34. regscale/integrations/commercial/wizv2/sbom.py +1 -1
  35. regscale/integrations/commercial/wizv2/scanner.py +40 -100
  36. regscale/integrations/commercial/wizv2/utils/__init__.py +48 -0
  37. regscale/integrations/commercial/wizv2/{utils.py → utils/main.py} +116 -61
  38. regscale/integrations/commercial/wizv2/variables.py +89 -3
  39. regscale/integrations/compliance_integration.py +0 -46
  40. regscale/integrations/control_matcher.py +22 -3
  41. regscale/integrations/due_date_handler.py +14 -8
  42. regscale/integrations/public/fedramp/docx_parser.py +10 -1
  43. regscale/integrations/public/fedramp/fedramp_cis_crm.py +393 -340
  44. regscale/integrations/public/fedramp/fedramp_five.py +1 -1
  45. regscale/integrations/scanner_integration.py +127 -57
  46. regscale/models/integration_models/cisa_kev_data.json +132 -9
  47. regscale/models/integration_models/qualys.py +3 -4
  48. regscale/models/integration_models/synqly_models/capabilities.json +1 -1
  49. regscale/models/integration_models/synqly_models/connectors/vulnerabilities.py +24 -7
  50. regscale/models/integration_models/synqly_models/synqly_model.py +8 -1
  51. regscale/models/regscale_models/control_implementation.py +1 -1
  52. regscale/models/regscale_models/issue.py +0 -1
  53. {regscale_cli-6.26.0.0.dist-info → regscale_cli-6.27.0.1.dist-info}/METADATA +1 -17
  54. {regscale_cli-6.26.0.0.dist-info → regscale_cli-6.27.0.1.dist-info}/RECORD +94 -61
  55. tests/regscale/integrations/commercial/test_jira.py +481 -91
  56. tests/regscale/integrations/commercial/test_wiz.py +96 -200
  57. tests/regscale/integrations/commercial/wizv2/__init__.py +1 -1
  58. tests/regscale/integrations/commercial/wizv2/compliance/__init__.py +1 -0
  59. tests/regscale/integrations/commercial/wizv2/compliance/test_helpers.py +903 -0
  60. tests/regscale/integrations/commercial/wizv2/core/__init__.py +1 -0
  61. tests/regscale/integrations/commercial/wizv2/core/test_auth.py +701 -0
  62. tests/regscale/integrations/commercial/wizv2/core/test_client.py +1037 -0
  63. tests/regscale/integrations/commercial/wizv2/core/test_file_operations.py +989 -0
  64. tests/regscale/integrations/commercial/wizv2/fetchers/__init__.py +1 -0
  65. tests/regscale/integrations/commercial/wizv2/fetchers/test_policy_assessment.py +805 -0
  66. tests/regscale/integrations/commercial/wizv2/parsers/__init__.py +1 -0
  67. tests/regscale/integrations/commercial/wizv2/parsers/test_main.py +1153 -0
  68. tests/regscale/integrations/commercial/wizv2/processors/__init__.py +1 -0
  69. tests/regscale/integrations/commercial/wizv2/processors/test_finding.py +671 -0
  70. tests/regscale/integrations/commercial/wizv2/test_WizDataMixin.py +537 -0
  71. tests/regscale/integrations/commercial/wizv2/test_click_comprehensive.py +851 -0
  72. tests/regscale/integrations/commercial/wizv2/test_compliance_report_comprehensive.py +910 -0
  73. tests/regscale/integrations/commercial/wizv2/test_file_cleanup.py +283 -0
  74. tests/regscale/integrations/commercial/wizv2/test_file_operations.py +260 -0
  75. tests/regscale/integrations/commercial/wizv2/test_issue.py +1 -1
  76. tests/regscale/integrations/commercial/wizv2/test_issue_comprehensive.py +1203 -0
  77. tests/regscale/integrations/commercial/wizv2/test_reports.py +497 -0
  78. tests/regscale/integrations/commercial/wizv2/test_sbom.py +643 -0
  79. tests/regscale/integrations/commercial/wizv2/test_scanner_comprehensive.py +805 -0
  80. tests/regscale/integrations/commercial/wizv2/test_wiz_click_client_id.py +1 -1
  81. tests/regscale/integrations/commercial/wizv2/test_wiz_compliance_report.py +72 -29
  82. tests/regscale/integrations/commercial/wizv2/test_wiz_findings_comprehensive.py +364 -0
  83. tests/regscale/integrations/commercial/wizv2/test_wiz_inventory_comprehensive.py +644 -0
  84. tests/regscale/integrations/commercial/wizv2/test_wizv2.py +946 -78
  85. tests/regscale/integrations/commercial/wizv2/test_wizv2_utils.py +97 -202
  86. tests/regscale/integrations/commercial/wizv2/utils/__init__.py +1 -0
  87. tests/regscale/integrations/commercial/wizv2/utils/test_main.py +1523 -0
  88. tests/regscale/integrations/public/test_fedramp.py +301 -0
  89. tests/regscale/integrations/test_control_matcher.py +83 -0
  90. regscale/integrations/commercial/wizv2/policy_compliance.py +0 -3543
  91. tests/regscale/integrations/commercial/wizv2/test_wiz_policy_compliance.py +0 -750
  92. /regscale/integrations/commercial/wizv2/{wiz_auth.py → core/auth.py} +0 -0
  93. {regscale_cli-6.26.0.0.dist-info → regscale_cli-6.27.0.1.dist-info}/LICENSE +0 -0
  94. {regscale_cli-6.26.0.0.dist-info → regscale_cli-6.27.0.1.dist-info}/WHEEL +0 -0
  95. {regscale_cli-6.26.0.0.dist-info → regscale_cli-6.27.0.1.dist-info}/entry_points.txt +0 -0
  96. {regscale_cli-6.26.0.0.dist-info → regscale_cli-6.27.0.1.dist-info}/top_level.txt +0 -0
@@ -14,11 +14,12 @@ logger = logging.getLogger("regscale")
14
14
  class TestWizUtils(unittest.TestCase):
15
15
  """Test cases for Wiz utility functions."""
16
16
 
17
- @patch("regscale.integrations.commercial.wizv2.utils.download_report")
18
- @patch("regscale.integrations.commercial.wizv2.utils.rerun_expired_report")
19
- @patch("regscale.integrations.commercial.wizv2.utils.CHECK_INTERVAL_FOR_DOWNLOAD_REPORT", 0.001)
20
- @patch("regscale.integrations.commercial.wizv2.utils.MAX_RETRIES", 3)
21
- def test_get_report_url_and_status_completed(self, mock_rerun_report, mock_download_report):
17
+ @patch("regscale.integrations.commercial.wizv2.utils.main.time.sleep")
18
+ @patch("regscale.integrations.commercial.wizv2.utils.main.download_report")
19
+ @patch("regscale.integrations.commercial.wizv2.utils.main.rerun_expired_report")
20
+ @patch("regscale.integrations.commercial.wizv2.utils.main.CHECK_INTERVAL_FOR_DOWNLOAD_REPORT", 0.001)
21
+ @patch("regscale.integrations.commercial.wizv2.utils.main.MAX_RETRIES", 3)
22
+ def test_get_report_url_and_status_completed(self, mock_rerun_report, mock_download_report, mock_sleep):
22
23
  """Test get_report_url_and_status with COMPLETED status."""
23
24
  # Mock response for completed report
24
25
  mock_response = MagicMock()
@@ -35,13 +36,17 @@ class TestWizUtils(unittest.TestCase):
35
36
  self.assertEqual(result, "https://example.com/report.csv")
36
37
  mock_download_report.assert_called_once_with({"reportId": "test-report-id"})
37
38
  mock_rerun_report.assert_not_called()
38
-
39
- @patch("regscale.integrations.commercial.wizv2.utils.download_report")
40
- @patch("regscale.integrations.commercial.wizv2.utils.rerun_expired_report")
41
- @patch("regscale.integrations.commercial.wizv2.utils.get_report_url_and_status")
42
- @patch("regscale.integrations.commercial.wizv2.utils.CHECK_INTERVAL_FOR_DOWNLOAD_REPORT", 0.001)
43
- @patch("regscale.integrations.commercial.wizv2.utils.MAX_RETRIES", 3)
44
- def test_get_report_url_and_status_expired(self, mock_recursive_call, mock_rerun_report, mock_download_report):
39
+ mock_sleep.assert_not_called() # Should not sleep on first success
40
+
41
+ @patch("regscale.integrations.commercial.wizv2.utils.main.time.sleep")
42
+ @patch("regscale.integrations.commercial.wizv2.utils.main.download_report")
43
+ @patch("regscale.integrations.commercial.wizv2.utils.main.rerun_expired_report")
44
+ @patch("regscale.integrations.commercial.wizv2.utils.main.get_report_url_and_status")
45
+ @patch("regscale.integrations.commercial.wizv2.utils.main.CHECK_INTERVAL_FOR_DOWNLOAD_REPORT", 0.001)
46
+ @patch("regscale.integrations.commercial.wizv2.utils.main.MAX_RETRIES", 3)
47
+ def test_get_report_url_and_status_expired(
48
+ self, mock_recursive_call, mock_rerun_report, mock_download_report, mock_sleep
49
+ ):
45
50
  """Test get_report_url_and_status with EXPIRED status."""
46
51
  # Mock response for expired report
47
52
  mock_response = MagicMock()
@@ -65,14 +70,16 @@ class TestWizUtils(unittest.TestCase):
65
70
  mock_download_report.assert_called_once_with({"reportId": "test-report-id"})
66
71
  mock_rerun_report.assert_called_once_with({"reportId": "test-report-id"})
67
72
  mock_recursive_call.assert_called_once_with("test-report-id")
68
-
69
- @patch("regscale.integrations.commercial.wizv2.utils.download_report")
70
- @patch("regscale.integrations.commercial.wizv2.utils.rerun_expired_report")
71
- @patch("regscale.integrations.commercial.wizv2.utils.CHECK_INTERVAL_FOR_DOWNLOAD_REPORT", 0.001)
72
- @patch("regscale.integrations.commercial.wizv2.utils.MAX_RETRIES", 5)
73
- def test_get_report_url_and_status_rate_limit(self, mock_rerun_report, mock_download_report):
73
+ mock_sleep.assert_not_called() # Should not sleep on first call before recursion
74
+
75
+ @patch("regscale.integrations.commercial.wizv2.utils.main.time.sleep")
76
+ @patch("regscale.integrations.commercial.wizv2.utils.main.download_report")
77
+ @patch("regscale.integrations.commercial.wizv2.utils.main.rerun_expired_report")
78
+ @patch("regscale.integrations.commercial.wizv2.utils.main.CHECK_INTERVAL_FOR_DOWNLOAD_REPORT", 0.001)
79
+ @patch("regscale.integrations.commercial.wizv2.utils.main.MAX_RETRIES", 5)
80
+ def test_get_report_url_and_status_rate_limit(self, mock_rerun_report, mock_download_report, mock_sleep):
74
81
  """Test get_report_url_and_status with rate limit error."""
75
- from regscale.integrations.commercial.wizv2.constants import RATE_LIMIT_MSG
82
+ from regscale.integrations.commercial.wizv2.core.constants import RATE_LIMIT_MSG
76
83
 
77
84
  # Mock response with rate limit error
78
85
  mock_response = MagicMock()
@@ -94,21 +101,22 @@ class TestWizUtils(unittest.TestCase):
94
101
  # Configure mock to return different responses on subsequent calls
95
102
  mock_download_report.side_effect = [mock_response, mock_response2]
96
103
 
97
- with patch("time.sleep") as mock_sleep:
98
- # Call the function
99
- result = get_report_url_and_status("test-report-id")
100
-
101
- # Verify the result
102
- self.assertEqual(result, "https://example.com/report.csv")
103
- self.assertEqual(mock_download_report.call_count, 2)
104
- mock_rerun_report.assert_not_called()
105
- self.assertEqual(mock_sleep.call_count, 5)
106
-
107
- @patch("regscale.integrations.commercial.wizv2.utils.download_report")
108
- @patch("regscale.integrations.commercial.wizv2.utils.rerun_expired_report")
109
- @patch("regscale.integrations.commercial.wizv2.utils.CHECK_INTERVAL_FOR_DOWNLOAD_REPORT", 0.001)
110
- @patch("regscale.integrations.commercial.wizv2.utils.MAX_RETRIES", 3)
111
- def test_get_report_url_and_status_failed_response(self, mock_rerun_report, mock_download_report):
104
+ # Call the function
105
+ result = get_report_url_and_status("test-report-id")
106
+
107
+ # Verify the result
108
+ self.assertEqual(result, "https://example.com/report.csv")
109
+ self.assertEqual(mock_download_report.call_count, 2)
110
+ mock_rerun_report.assert_not_called()
111
+ # Sleep is called twice: once for rate limit, once for retry interval
112
+ self.assertEqual(mock_sleep.call_count, 2)
113
+
114
+ @patch("regscale.integrations.commercial.wizv2.utils.main.time.sleep")
115
+ @patch("regscale.integrations.commercial.wizv2.utils.main.download_report")
116
+ @patch("regscale.integrations.commercial.wizv2.utils.main.rerun_expired_report")
117
+ @patch("regscale.integrations.commercial.wizv2.utils.main.CHECK_INTERVAL_FOR_DOWNLOAD_REPORT", 0.001)
118
+ @patch("regscale.integrations.commercial.wizv2.utils.main.MAX_RETRIES", 3)
119
+ def test_get_report_url_and_status_failed_response(self, mock_rerun_report, mock_download_report, mock_sleep):
112
120
  """Test get_report_url_and_status with failed response."""
113
121
  # Mock failed response
114
122
  mock_response = MagicMock()
@@ -123,11 +131,12 @@ class TestWizUtils(unittest.TestCase):
123
131
  mock_download_report.assert_called_once_with({"reportId": "test-report-id"})
124
132
  mock_rerun_report.assert_not_called()
125
133
 
126
- @patch("regscale.integrations.commercial.wizv2.utils.download_report")
127
- @patch("regscale.integrations.commercial.wizv2.utils.rerun_expired_report")
128
- @patch("regscale.integrations.commercial.wizv2.utils.CHECK_INTERVAL_FOR_DOWNLOAD_REPORT", 0.001)
129
- @patch("regscale.integrations.commercial.wizv2.utils.MAX_RETRIES", 3)
130
- def test_get_report_url_and_status_none_response(self, mock_rerun_report, mock_download_report):
134
+ @patch("regscale.integrations.commercial.wizv2.utils.main.time.sleep")
135
+ @patch("regscale.integrations.commercial.wizv2.utils.main.download_report")
136
+ @patch("regscale.integrations.commercial.wizv2.utils.main.rerun_expired_report")
137
+ @patch("regscale.integrations.commercial.wizv2.utils.main.CHECK_INTERVAL_FOR_DOWNLOAD_REPORT", 0.001)
138
+ @patch("regscale.integrations.commercial.wizv2.utils.main.MAX_RETRIES", 3)
139
+ def test_get_report_url_and_status_none_response(self, mock_rerun_report, mock_download_report, mock_sleep):
131
140
  """Test get_report_url_and_status with None response."""
132
141
  # Mock None response
133
142
  mock_download_report.return_value = None
@@ -140,11 +149,12 @@ class TestWizUtils(unittest.TestCase):
140
149
  mock_download_report.assert_called_once_with({"reportId": "test-report-id"})
141
150
  mock_rerun_report.assert_not_called()
142
151
 
143
- @patch("regscale.integrations.commercial.wizv2.utils.download_report")
144
- @patch("regscale.integrations.commercial.wizv2.utils.rerun_expired_report")
145
- @patch("regscale.integrations.commercial.wizv2.utils.CHECK_INTERVAL_FOR_DOWNLOAD_REPORT", 0.001)
146
- @patch("regscale.integrations.commercial.wizv2.utils.MAX_RETRIES", 3) # Reduce retries for faster testing
147
- def test_get_report_url_and_status_other_error(self, mock_rerun_report, mock_download_report):
152
+ @patch("regscale.integrations.commercial.wizv2.utils.main.time.sleep")
153
+ @patch("regscale.integrations.commercial.wizv2.utils.main.download_report")
154
+ @patch("regscale.integrations.commercial.wizv2.utils.main.rerun_expired_report")
155
+ @patch("regscale.integrations.commercial.wizv2.utils.main.CHECK_INTERVAL_FOR_DOWNLOAD_REPORT", 0.001)
156
+ @patch("regscale.integrations.commercial.wizv2.utils.main.MAX_RETRIES", 3) # Reduce retries for faster testing
157
+ def test_get_report_url_and_status_other_error(self, mock_rerun_report, mock_download_report, mock_sleep):
148
158
  """Test get_report_url_and_status with other error in response."""
149
159
  # Mock response with other error
150
160
  mock_response = MagicMock()
@@ -161,11 +171,12 @@ class TestWizUtils(unittest.TestCase):
161
171
  self.assertEqual(mock_download_report.call_count, 3)
162
172
  mock_rerun_report.assert_not_called()
163
173
 
164
- @patch("regscale.integrations.commercial.wizv2.utils.download_report")
165
- @patch("regscale.integrations.commercial.wizv2.utils.rerun_expired_report")
166
- @patch("regscale.integrations.commercial.wizv2.utils.CHECK_INTERVAL_FOR_DOWNLOAD_REPORT", 0.001)
167
- @patch("regscale.integrations.commercial.wizv2.utils.MAX_RETRIES", 3) # Reduce retries for faster testing
168
- def test_get_report_url_and_status_unknown_status(self, mock_rerun_report, mock_download_report):
174
+ @patch("regscale.integrations.commercial.wizv2.utils.main.time.sleep")
175
+ @patch("regscale.integrations.commercial.wizv2.utils.main.download_report")
176
+ @patch("regscale.integrations.commercial.wizv2.utils.main.rerun_expired_report")
177
+ @patch("regscale.integrations.commercial.wizv2.utils.main.CHECK_INTERVAL_FOR_DOWNLOAD_REPORT", 0.001)
178
+ @patch("regscale.integrations.commercial.wizv2.utils.main.MAX_RETRIES", 3) # Reduce retries for faster testing
179
+ def test_get_report_url_and_status_unknown_status(self, mock_rerun_report, mock_download_report, mock_sleep):
169
180
  """Test get_report_url_and_status with unknown status."""
170
181
  # Mock response with unknown status
171
182
  mock_response = MagicMock()
@@ -182,11 +193,12 @@ class TestWizUtils(unittest.TestCase):
182
193
  self.assertEqual(mock_download_report.call_count, 3)
183
194
  mock_rerun_report.assert_not_called()
184
195
 
185
- @patch("regscale.integrations.commercial.wizv2.utils.download_report")
186
- @patch("regscale.integrations.commercial.wizv2.utils.rerun_expired_report")
187
- @patch("regscale.integrations.commercial.wizv2.utils.CHECK_INTERVAL_FOR_DOWNLOAD_REPORT", 0.001)
188
- @patch("regscale.integrations.commercial.wizv2.utils.MAX_RETRIES", 3) # Reduce retries for faster testing
189
- def test_get_report_url_and_status_missing_status(self, mock_rerun_report, mock_download_report):
196
+ @patch("regscale.integrations.commercial.wizv2.utils.main.time.sleep")
197
+ @patch("regscale.integrations.commercial.wizv2.utils.main.download_report")
198
+ @patch("regscale.integrations.commercial.wizv2.utils.main.rerun_expired_report")
199
+ @patch("regscale.integrations.commercial.wizv2.utils.main.CHECK_INTERVAL_FOR_DOWNLOAD_REPORT", 0.001)
200
+ @patch("regscale.integrations.commercial.wizv2.utils.main.MAX_RETRIES", 3) # Reduce retries for faster testing
201
+ def test_get_report_url_and_status_missing_status(self, mock_rerun_report, mock_download_report, mock_sleep):
190
202
  """Test get_report_url_and_status with missing status in response."""
191
203
  # Mock response with missing status
192
204
  mock_response = MagicMock()
@@ -203,12 +215,13 @@ class TestWizUtils(unittest.TestCase):
203
215
  self.assertEqual(mock_download_report.call_count, 3)
204
216
  mock_rerun_report.assert_not_called()
205
217
 
206
- @patch("regscale.integrations.commercial.wizv2.utils.download_report")
207
- @patch("regscale.integrations.commercial.wizv2.utils.rerun_expired_report")
208
- @patch("regscale.integrations.commercial.wizv2.utils.CHECK_INTERVAL_FOR_DOWNLOAD_REPORT", 0.001)
209
- @patch("regscale.integrations.commercial.wizv2.utils.MAX_RETRIES", 3)
218
+ @patch("regscale.integrations.commercial.wizv2.utils.main.time.sleep")
219
+ @patch("regscale.integrations.commercial.wizv2.utils.main.download_report")
220
+ @patch("regscale.integrations.commercial.wizv2.utils.main.rerun_expired_report")
221
+ @patch("regscale.integrations.commercial.wizv2.utils.main.CHECK_INTERVAL_FOR_DOWNLOAD_REPORT", 0.001)
222
+ @patch("regscale.integrations.commercial.wizv2.utils.main.MAX_RETRIES", 3)
210
223
  def test_get_report_url_and_status_multiple_attempts_before_completion(
211
- self, mock_rerun_report, mock_download_report
224
+ self, mock_rerun_report, mock_download_report, mock_sleep
212
225
  ):
213
226
  """Test get_report_url_and_status with multiple attempts before completion."""
214
227
  # Mock responses: first two with unknown status, third with completed
@@ -229,132 +242,14 @@ class TestWizUtils(unittest.TestCase):
229
242
  # Configure mock to return different responses on subsequent calls
230
243
  mock_download_report.side_effect = [mock_response1, mock_response2, mock_response3]
231
244
 
232
- with patch("time.sleep") as mock_sleep:
233
- # Call the function
234
- result = get_report_url_and_status("test-report-id")
235
-
236
- # Verify the result
237
- self.assertEqual(result, "https://example.com/report.csv")
238
- self.assertEqual(mock_download_report.call_count, 3)
239
- # Should sleep twice (after first and second attempts)
240
- self.assertEqual(mock_sleep.call_count, 2)
241
- mock_rerun_report.assert_not_called()
242
-
243
- @patch("regscale.integrations.commercial.wizv2.utils.download_report")
244
- @patch("regscale.integrations.commercial.wizv2.utils.rerun_expired_report")
245
- @patch("regscale.integrations.commercial.wizv2.utils.MAX_RETRIES", 3)
246
- def test_get_report_url_and_status_rate_limit(self, mock_rerun_report, mock_download_report):
247
- """Test get_report_url_and_status with rate limit error."""
248
- from regscale.integrations.commercial.wizv2.constants import RATE_LIMIT_MSG
249
- import time
250
-
251
- # Mock response with rate limit error
252
- mock_response = MagicMock()
253
- mock_response.ok = True
254
- mock_response.json.return_value = {
255
- "errors": [{"message": "Rate limit exceeded", "extensions": {"retryAfter": 5}}]
256
- }
257
- mock_download_report.return_value = mock_response
258
-
259
- # Mock second response for successful completion
260
- mock_response2 = MagicMock()
261
- mock_response2.ok = True
262
- mock_response2.json.return_value = {
263
- "data": {"report": {"lastRun": {"status": "COMPLETED", "url": "https://example.com/report.csv"}}}
264
- }
265
-
266
- # Configure mock to return different responses on subsequent calls
267
- mock_download_report.side_effect = [mock_response, mock_response2]
268
-
269
- with patch("time.sleep") as mock_sleep:
270
- # Call the function
271
- result = get_report_url_and_status("test-report-id")
272
-
273
- # Verify the result
274
- self.assertEqual(result, "https://example.com/report.csv")
275
- self.assertEqual(mock_download_report.call_count, 2)
276
- # Check that time.sleep was called with the rate limit retry value (5)
277
- mock_sleep.assert_any_call(5)
278
- mock_rerun_report.assert_not_called()
279
-
280
- @patch("regscale.integrations.commercial.wizv2.utils.download_report")
281
- @patch("regscale.integrations.commercial.wizv2.utils.rerun_expired_report")
282
- @patch("regscale.integrations.commercial.wizv2.utils.CHECK_INTERVAL_FOR_DOWNLOAD_REPORT", 0.001)
283
- def test_get_report_url_and_status_other_error(self, mock_rerun_report, mock_download_report):
284
- """Test get_report_url_and_status with other error in response."""
285
- # Mock response with other error
286
- mock_response = MagicMock()
287
- mock_response.ok = True
288
- mock_response.json.return_value = {"errors": [{"message": "Some other error occurred"}]}
289
- mock_download_report.return_value = mock_response
290
-
291
- # Call the function and expect exception after max retries
292
- with self.assertRaises(Exception) as context:
293
- get_report_url_and_status("test-report-id")
294
-
295
- self.assertIn("Download failed, exceeding the maximum number of retries", str(context.exception))
296
- # Should be called MAX_RETRIES times
297
- self.assertEqual(mock_download_report.call_count, 100)
298
- mock_rerun_report.assert_not_called()
299
-
300
- @patch("regscale.integrations.commercial.wizv2.utils.download_report")
301
- @patch("regscale.integrations.commercial.wizv2.utils.rerun_expired_report")
302
- @patch("regscale.integrations.commercial.wizv2.utils.CHECK_INTERVAL_FOR_DOWNLOAD_REPORT", 0.001)
303
- def test_get_report_url_and_status_unknown_status(self, mock_rerun_report, mock_download_report):
304
- """Test get_report_url_and_status with unknown status."""
305
- # Mock response with unknown status
306
- mock_response = MagicMock()
307
- mock_response.ok = True
308
- mock_response.json.return_value = {"data": {"report": {"lastRun": {"status": "UNKNOWN_STATUS"}}}}
309
- mock_download_report.return_value = mock_response
310
-
311
- # Call the function and expect exception after max retries
312
- with self.assertRaises(Exception) as context:
313
- get_report_url_and_status("test-report-id")
314
-
315
- self.assertIn("Download failed, exceeding the maximum number of retries", str(context.exception))
316
- # Should be called MAX_RETRIES times
317
- self.assertEqual(mock_download_report.call_count, 100)
318
- mock_rerun_report.assert_not_called()
319
-
320
- @patch("regscale.integrations.commercial.wizv2.utils.download_report")
321
- @patch("regscale.integrations.commercial.wizv2.utils.rerun_expired_report")
322
- @patch("regscale.integrations.commercial.wizv2.utils.CHECK_INTERVAL_FOR_DOWNLOAD_REPORT", 0.001)
323
- def test_get_report_url_and_status_missing_status(self, mock_rerun_report, mock_download_report):
324
- """Test get_report_url_and_status with missing status in response."""
325
- # Mock response with missing status
326
- mock_response = MagicMock()
327
- mock_response.ok = True
328
- mock_response.json.return_value = {"data": {"report": {"lastRun": {}}}}
329
- mock_download_report.return_value = mock_response
330
-
331
- # Call the function and expect exception after max retries
332
- with self.assertRaises(Exception) as context:
333
- get_report_url_and_status("test-report-id")
334
-
335
- self.assertIn("Download failed, exceeding the maximum number of retries", str(context.exception))
336
- # Should be called MAX_RETRIES times
337
- self.assertEqual(mock_download_report.call_count, 100)
338
- mock_rerun_report.assert_not_called()
339
-
340
- @patch("regscale.integrations.commercial.wizv2.utils.download_report")
341
- @patch("regscale.integrations.commercial.wizv2.utils.rerun_expired_report")
342
- @patch("regscale.integrations.commercial.wizv2.utils.CHECK_INTERVAL_FOR_DOWNLOAD_REPORT", 0.001)
343
- def test_get_report_url_and_status_missing_data(self, mock_rerun_report, mock_download_report):
344
- """Test get_report_url_and_status with missing data in response."""
345
- # Mock response with missing data
346
- mock_response = MagicMock()
347
- mock_response.ok = True
348
- mock_response.json.return_value = {}
349
- mock_download_report.return_value = mock_response
350
-
351
- # Call the function and expect exception after max retries
352
- with self.assertRaises(Exception) as context:
353
- get_report_url_and_status("test-report-id")
245
+ # Call the function
246
+ result = get_report_url_and_status("test-report-id")
354
247
 
355
- self.assertIn("Download failed, exceeding the maximum number of retries", str(context.exception))
356
- # Should be called MAX_RETRIES times
357
- self.assertEqual(mock_download_report.call_count, 100)
248
+ # Verify the result
249
+ self.assertEqual(result, "https://example.com/report.csv")
250
+ self.assertEqual(mock_download_report.call_count, 3)
251
+ # Should sleep twice (after first and second attempts)
252
+ self.assertEqual(mock_sleep.call_count, 2)
358
253
  mock_rerun_report.assert_not_called()
359
254
 
360
255
 
@@ -371,8 +266,8 @@ class TestGetOrCreateReportId(unittest.TestCase):
371
266
  ]
372
267
  self.target_framework = "NIST_SP_800-53_Revision_5"
373
268
 
374
- @patch("regscale.integrations.commercial.wizv2.utils.Application")
375
- @patch("regscale.integrations.commercial.wizv2.utils.is_report_expired")
269
+ @patch("regscale.integrations.commercial.wizv2.utils.main.Application")
270
+ @patch("regscale.integrations.commercial.wizv2.utils.main.is_report_expired")
376
271
  def test_get_or_create_report_id_existing_valid_report(self, mock_is_expired, mock_application):
377
272
  """Test returning existing report ID when report is valid (not expired)."""
378
273
  # Mock Application
@@ -400,9 +295,9 @@ class TestGetOrCreateReportId(unittest.TestCase):
400
295
  mock_app.config.get.assert_called_once_with("wizReportAge", 15)
401
296
  mock_is_expired.assert_called_once_with("2023-07-15T14:37:55.450532Z", 15)
402
297
 
403
- @patch("regscale.integrations.commercial.wizv2.utils.Application")
404
- @patch("regscale.integrations.commercial.wizv2.utils.is_report_expired")
405
- @patch("regscale.integrations.commercial.wizv2.utils.create_compliance_report")
298
+ @patch("regscale.integrations.commercial.wizv2.utils.main.Application")
299
+ @patch("regscale.integrations.commercial.wizv2.utils.main.is_report_expired")
300
+ @patch("regscale.integrations.commercial.wizv2.utils.main.create_compliance_report")
406
301
  def test_get_or_create_report_id_existing_expired_report(
407
302
  self, mock_create_report, mock_is_expired, mock_application
408
303
  ):
@@ -440,8 +335,8 @@ class TestGetOrCreateReportId(unittest.TestCase):
440
335
  framework_id="framework-1",
441
336
  )
442
337
 
443
- @patch("regscale.integrations.commercial.wizv2.utils.Application")
444
- @patch("regscale.integrations.commercial.wizv2.utils.create_compliance_report")
338
+ @patch("regscale.integrations.commercial.wizv2.utils.main.Application")
339
+ @patch("regscale.integrations.commercial.wizv2.utils.main.create_compliance_report")
445
340
  def test_get_or_create_report_id_no_existing_report(self, mock_create_report, mock_application):
446
341
  """Test creating new report when no existing report is found."""
447
342
  # Mock Application
@@ -467,8 +362,8 @@ class TestGetOrCreateReportId(unittest.TestCase):
467
362
  framework_id="framework-1",
468
363
  )
469
364
 
470
- @patch("regscale.integrations.commercial.wizv2.utils.Application")
471
- @patch("regscale.integrations.commercial.wizv2.utils.is_report_expired")
365
+ @patch("regscale.integrations.commercial.wizv2.utils.main.Application")
366
+ @patch("regscale.integrations.commercial.wizv2.utils.main.is_report_expired")
472
367
  def test_get_or_create_report_id_missing_run_at(self, mock_is_expired, mock_application):
473
368
  """Test behavior when existing report has no runAt timestamp."""
474
369
  # Mock Application
@@ -497,7 +392,7 @@ class TestGetOrCreateReportId(unittest.TestCase):
497
392
  # is_report_expired should not be called when runAt is missing
498
393
  mock_is_expired.assert_not_called()
499
394
 
500
- @patch("regscale.integrations.commercial.wizv2.utils.Application")
395
+ @patch("regscale.integrations.commercial.wizv2.utils.main.Application")
501
396
  def test_get_or_create_report_id_framework_not_found(self, mock_application):
502
397
  """Test ValueError when target framework is not in frameworks list."""
503
398
  # Mock Application
@@ -518,8 +413,8 @@ class TestGetOrCreateReportId(unittest.TestCase):
518
413
  # The actual error message from list.index() is different
519
414
  self.assertIn("is not in list", str(context.exception))
520
415
 
521
- @patch("regscale.integrations.commercial.wizv2.utils.Application")
522
- @patch("regscale.integrations.commercial.wizv2.utils.is_report_expired")
416
+ @patch("regscale.integrations.commercial.wizv2.utils.main.Application")
417
+ @patch("regscale.integrations.commercial.wizv2.utils.main.is_report_expired")
523
418
  def test_get_or_create_report_id_custom_report_age(self, mock_is_expired, mock_application):
524
419
  """Test using custom wizReportAge configuration."""
525
420
  # Mock Application with custom age
@@ -547,9 +442,9 @@ class TestGetOrCreateReportId(unittest.TestCase):
547
442
  mock_app.config.get.assert_called_once_with("wizReportAge", 15)
548
443
  mock_is_expired.assert_called_once_with("2023-07-15T14:37:55.450532Z", 30)
549
444
 
550
- @patch("regscale.integrations.commercial.wizv2.utils.Application")
551
- @patch("regscale.integrations.commercial.wizv2.utils.is_report_expired")
552
- @patch("regscale.integrations.commercial.wizv2.utils.create_compliance_report")
445
+ @patch("regscale.integrations.commercial.wizv2.utils.main.Application")
446
+ @patch("regscale.integrations.commercial.wizv2.utils.main.is_report_expired")
447
+ @patch("regscale.integrations.commercial.wizv2.utils.main.create_compliance_report")
553
448
  def test_get_or_create_report_id_multiple_reports_first_match(
554
449
  self, mock_create_report, mock_is_expired, mock_application
555
450
  ):
@@ -585,9 +480,9 @@ class TestGetOrCreateReportId(unittest.TestCase):
585
480
  mock_is_expired.assert_called_once_with("2023-07-15T14:37:55.450532Z", 15)
586
481
  mock_create_report.assert_not_called()
587
482
 
588
- @patch("regscale.integrations.commercial.wizv2.utils.Application")
589
- @patch("regscale.integrations.commercial.wizv2.utils.is_report_expired")
590
- @patch("regscale.integrations.commercial.wizv2.utils.create_compliance_report")
483
+ @patch("regscale.integrations.commercial.wizv2.utils.main.Application")
484
+ @patch("regscale.integrations.commercial.wizv2.utils.main.is_report_expired")
485
+ @patch("regscale.integrations.commercial.wizv2.utils.main.create_compliance_report")
591
486
  def test_get_or_create_report_id_different_report_names(
592
487
  self, mock_create_report, mock_is_expired, mock_application
593
488
  ):
@@ -0,0 +1 @@
1
+ """Tests for Wiz V2 Utils"""