|
1 | | -from unittest import TestCase, mock |
| 1 | +from unittest import mock |
| 2 | +import yaml |
| 3 | + |
2 | 4 | import pandas |
3 | 5 | import pytest |
4 | 6 |
|
| 7 | +from process_report import settings |
5 | 8 | from process_report.tests import util as test_utils |
| 9 | +from process_report.tests.base import BaseTestCaseWithTempDir |
| 10 | + |
6 | 11 |
|
| 12 | +class TestColdfrontFetchProcessor(BaseTestCaseWithTempDir): |
| 13 | + def setUp(self): |
| 14 | + # To trigger fetch from Coldfront |
| 15 | + settings.invoice_settings.keycloak_client_id = "foo" |
| 16 | + return super().setUp() |
7 | 17 |
|
8 | | -class TestColdfrontFetchProcessor(TestCase): |
9 | 18 | def _get_test_invoice( |
10 | 19 | self, |
11 | 20 | allocation_project_id, |
@@ -259,3 +268,93 @@ def test_missing_project_cluster_tuples(self, mock_get_allocation_data): |
259 | 268 | assert str(cm.value) == ( |
260 | 269 | f"Projects {expected_missing} not found in Coldfront and are billable! Please check the project names" |
261 | 270 | ) |
| 271 | + |
| 272 | + @mock.patch( |
| 273 | + "process_report.processors.coldfront_fetch_processor.ColdfrontFetchProcessor._fetch_coldfront_allocation_api", |
| 274 | + ) |
| 275 | + def test_supplement_api_data_used_when_coldfront_missing( |
| 276 | + self, mock_get_allocation_data |
| 277 | + ): |
| 278 | + """Supplement API rows are applied to invoice in _get_allocation_data().""" |
| 279 | + mock_get_allocation_data.return_value = self._get_mock_allocation_data( |
| 280 | + ["P1"], |
| 281 | + ["PI1"], |
| 282 | + ["IC1"], |
| 283 | + ["stack"], |
| 284 | + ) |
| 285 | + |
| 286 | + # Supplemental data should follow same structure as Coldfront data, |
| 287 | + # only missing "Is Course?" and "Institution-Specific Code" fields |
| 288 | + supplemental_df = self._get_mock_allocation_data( |
| 289 | + ["P2"], |
| 290 | + ["PI2"], |
| 291 | + ["Delete Institude Code"], |
| 292 | + ["stack"], |
| 293 | + ) |
| 294 | + del supplemental_df[0]["attributes"]["Institution-Specific Code"] |
| 295 | + |
| 296 | + supplemental_filepath = self.tempdir / "supplement.yaml" |
| 297 | + with open(supplemental_filepath, "w") as f: |
| 298 | + yaml.safe_dump(supplemental_df, f) |
| 299 | + |
| 300 | + test_invoice = self._get_test_invoice( |
| 301 | + ["P1", "P2"], cluster_name=["stack", "stack"] |
| 302 | + ) |
| 303 | + |
| 304 | + expected_invoice = self._get_test_invoice( |
| 305 | + ["P1", "P2"], |
| 306 | + ["P1-name", "P2-name"], |
| 307 | + ["PI1", "PI2"], |
| 308 | + ["IC1", "N/A"], |
| 309 | + ["stack", "stack"], |
| 310 | + [False, False], |
| 311 | + ) |
| 312 | + |
| 313 | + test_coldfront_fetch_proc = test_utils.new_coldfront_fetch_processor( |
| 314 | + data=test_invoice, coldfront_data_filepaths=[supplemental_filepath] |
| 315 | + ) |
| 316 | + test_coldfront_fetch_proc.process() |
| 317 | + output_invoice = test_coldfront_fetch_proc.data |
| 318 | + |
| 319 | + assert output_invoice.equals(expected_invoice) |
| 320 | + |
| 321 | + @mock.patch( |
| 322 | + "process_report.processors.coldfront_fetch_processor.ColdfrontFetchProcessor._fetch_coldfront_allocation_api", |
| 323 | + ) |
| 324 | + def test_duplicate_allocation_cluster_in_api_data(self, mock_get_allocation_data): |
| 325 | + """Test that a ValueError is raised when API data contains duplicate (allocation, cluster) pairs.""" |
| 326 | + mock_data = [ |
| 327 | + { |
| 328 | + "resource": {"name": "stack"}, |
| 329 | + "project": {"pi": "PI1"}, |
| 330 | + "attributes": { |
| 331 | + "Allocated Project ID": "P1", |
| 332 | + "Allocated Project Name": "P1-name", |
| 333 | + "Institution-Specific Code": "IC1", |
| 334 | + }, |
| 335 | + }, |
| 336 | + { |
| 337 | + "resource": {"name": "stack"}, |
| 338 | + "project": {"pi": "PI1"}, |
| 339 | + "attributes": { |
| 340 | + "Allocated Project ID": "P1", |
| 341 | + "Allocated Project Name": "P1-name", |
| 342 | + "Institution-Specific Code": "IC1", |
| 343 | + }, |
| 344 | + }, |
| 345 | + ] |
| 346 | + mock_get_allocation_data.return_value = mock_data |
| 347 | + |
| 348 | + test_invoice = self._get_test_invoice(["P1"], cluster_name=["stack"]) |
| 349 | + |
| 350 | + test_coldfront_fetch_proc = test_utils.new_coldfront_fetch_processor( |
| 351 | + data=test_invoice |
| 352 | + ) |
| 353 | + |
| 354 | + with pytest.raises(ValueError) as cm: |
| 355 | + test_coldfront_fetch_proc.process() |
| 356 | + |
| 357 | + assert ( |
| 358 | + str(cm.value) |
| 359 | + == "Found allocations matched more than once in API data: [('P1', 'stack')]" |
| 360 | + ) |
0 commit comments