diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 915b95a6..4e679d9a 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -5,6 +5,7 @@ Version History v7.1.7 ------ +* Convert narrativelog date_begin and date_end UTC datetimes to TAI. ``_ * Add recently added CSCs to SummaryState view on BTS. ``_ * Make channels layer group expiry parameter configurable through an environment variable. ``_ diff --git a/manager/api/tests/test_ole.py b/manager/api/tests/test_ole.py index 53c39054..56b1e919 100644 --- a/manager/api/tests/test_ole.py +++ b/manager/api/tests/test_ole.py @@ -28,6 +28,8 @@ from django.urls import reverse from rest_framework.test import APIClient +from manager.utils import DATETIME_ISO_FORMAT, get_tai_from_utc + @override_settings(DEBUG=True) class OLETestCase(TestCase): @@ -71,9 +73,9 @@ def setUp(self): "components": "MainTel", "primary_software_components": "None", "primary_hardware_components": "None", - "date_begin": "202200703-19:58:13", - "date_end": "20220704-19:25:13", - "time_lost": 10, + "date_begin": "2024-01-01T00:00:00.000000", + "date_end": "2024-01-01T00:10:00.000000", + "time_lost": 1, "level": 0, } @@ -139,6 +141,8 @@ def test_exposurelog_list(self): self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data), 0) + mock_ole_client.stop() + def test_simple_exposurelog_create(self): """Test exposurelog create.""" # Arrange: @@ -158,6 +162,8 @@ def test_simple_exposurelog_create(self): response = self.client.post(url, self.payload_full_exposure) self.assertEqual(response.status_code, 201) + mock_ole_client.stop() + def test_exposurelog_update(self): """Test exposurelog update.""" # Arrange: @@ -177,6 +183,8 @@ def test_exposurelog_update(self): response = self.client.put(url, self.payload_full_exposure) self.assertEqual(response.status_code, 200) + mock_ole_client.stop() + def test_exposurelog_create_with_jira(self): """Test exposurelog create with jira.""" # Arrange: @@ -222,6 +230,9 @@ def test_exposurelog_create_with_jira(self): response = self.client.post(url, self.payload_full_exposure_with_jira_comment) self.assertEqual(response.status_code, 201) + mock_jira_ticket_client.stop() + mock_ole_client.stop() + def test_exposurelog_update_with_jira(self): """Test exposurelog update with jira.""" # Arrange: @@ -267,6 +278,9 @@ def test_exposurelog_update_with_jira(self): response = self.client.put(url, self.payload_full_exposure_with_jira_comment) self.assertEqual(response.status_code, 200) + mock_jira_ticket_client.stop() + mock_ole_client.stop() + def test_narrativelog_list(self): """Test narrativelog list.""" # Arrange: @@ -287,6 +301,8 @@ def test_narrativelog_list(self): self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data), 0) + mock_ole_client.stop() + def test_simple_narrativelog_create(self): """Test narrativelog create.""" # Arrange: @@ -304,8 +320,26 @@ def test_simple_narrativelog_create(self): # Act: url = reverse("NarrativeLogs-list") response = self.client.post(url, self.payload_full_narrative) + + # Assert: self.assertEqual(response.status_code, 201) + # Check the date_begin and date_end arguments + # are transformed to TAI scale. + mock_ole_client_json_arg = mock_ole_client.call_args.kwargs["json"].dict() + date_begin_arg = mock_ole_client_json_arg["date_begin"] + date_end_arg = mock_ole_client_json_arg["date_end"] + payload_date_begin_formatted = get_tai_from_utc( + self.payload_full_narrative["date_begin"] + ).strftime("%Y-%m-%dT%H:%M:%S.%f") + payload_date_end_formatted = get_tai_from_utc( + self.payload_full_narrative["date_end"] + ).strftime("%Y-%m-%dT%H:%M:%S.%f") + assert date_begin_arg == payload_date_begin_formatted + assert date_end_arg == payload_date_end_formatted + + mock_ole_client.stop() + def test_narrativelog_update(self): """Test narrativelog update.""" # Arrange: @@ -323,8 +357,26 @@ def test_narrativelog_update(self): # Act: url = reverse("NarrativeLogs-detail", args=[1]) response = self.client.put(url, self.payload_full_narrative) + + # Assert self.assertEqual(response.status_code, 200) + # Check the date_begin and date_end arguments + # are transformed to TAI scale. + mock_ole_client_json_arg = mock_ole_client.call_args.kwargs["json"].dict() + date_begin_arg = mock_ole_client_json_arg["date_begin"] + date_end_arg = mock_ole_client_json_arg["date_end"] + payload_date_begin_formatted = get_tai_from_utc( + self.payload_full_narrative["date_begin"] + ).strftime(DATETIME_ISO_FORMAT) + payload_date_end_formatted = get_tai_from_utc( + self.payload_full_narrative["date_end"] + ).strftime(DATETIME_ISO_FORMAT) + assert date_begin_arg == payload_date_begin_formatted + assert date_end_arg == payload_date_end_formatted + + mock_ole_client.stop() + def test_narrative_log_create_with_jira(self): """Test narrativelog create with jira.""" # Arrange: @@ -370,6 +422,9 @@ def test_narrative_log_create_with_jira(self): response = self.client.post(url, self.payload_full_narrative_with_jira_comment) self.assertEqual(response.status_code, 201) + mock_jira_ticket_client.stop() + mock_ole_client.stop() + def test_narrative_log_update_with_jira(self): """Test narrativelog update with jira.""" # Arrange: @@ -415,6 +470,9 @@ def test_narrative_log_update_with_jira(self): response = self.client.put(url, self.payload_full_narrative_with_jira_comment) self.assertEqual(response.status_code, 200) + mock_jira_ticket_client.stop() + mock_ole_client.stop() + @override_settings(DEBUG=True) class NightReportTestCase(TestCase): @@ -485,6 +543,8 @@ def test_nightreport_list(self): self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data), 1) + mock_ole_client.stop() + def test_simple_nightreport_create(self): """Test nightreport create.""" # Arrange: @@ -504,6 +564,8 @@ def test_simple_nightreport_create(self): response = self.client.post(url, self.payload) self.assertEqual(response.status_code, 201) + mock_ole_client.stop() + def test_nightreport_update(self): """Test nightreport update.""" # Arrange: @@ -523,6 +585,8 @@ def test_nightreport_update(self): response = self.client.put(url, self.payload) self.assertEqual(response.status_code, 200) + mock_ole_client.stop() + def test_nightreport_delete(self): """Test nightreport delete.""" # Arrange: @@ -542,6 +606,8 @@ def test_nightreport_delete(self): response = self.client.delete(url) self.assertEqual(response.status_code, 200) + mock_ole_client.stop() + def test_nightreport_send(self): """Test nightreport send.""" # Arrange: @@ -578,6 +644,11 @@ def test_nightreport_send(self): response = self.client.post(url) self.assertEqual(response.status_code, 200) + mock_ole_client_get.stop() + mock_ole_client_patch.stop() + mock_get_jira_obs_report_client.stop() + mock_send_smtp_email_client.stop() + def test_nightreport_already_sent(self): """Test nightreport already sent.""" # Arrange: @@ -601,3 +672,5 @@ def test_nightreport_already_sent(self): response = self.client.post(url) self.assertEqual(response.status_code, 400) self.assertEqual(response.data, {"error": "Night report already sent"}) + + mock_ole_client_get.stop() diff --git a/manager/api/views.py b/manager/api/views.py index 77b3e1d2..92640568 100644 --- a/manager/api/views.py +++ b/manager/api/views.py @@ -65,11 +65,13 @@ AUTH_LDAP_3_SERVER_URI, ) from manager.utils import ( + DATETIME_ISO_FORMAT, CommandPermission, arrange_nightreport_email, get_jira_obs_report, get_obsday_from_tai, get_obsday_iso, + get_tai_from_utc, handle_jira_payload, send_smtp_email, upload_to_lfa, @@ -1307,6 +1309,16 @@ def create(self, request, *args, **kwargs): if "file[]" in json_data: del json_data["file[]"] + # Convert date_begin and date_end to TAI format + date_keys = { + "date_begin", + "date_end", + } + for key in date_keys: + if key in json_data: + tai_datetime = get_tai_from_utc(json_data[key]) + json_data[key] = tai_datetime.strftime(DATETIME_ISO_FORMAT) + # Split lists of values separated by comma array_keys = { "components", @@ -1365,6 +1377,16 @@ def update(self, request, pk=None, *args, **kwargs): if "file[]" in json_data: del json_data["file[]"] + # Convert date_begin and date_end to TAI format + date_keys = { + "date_begin", + "date_end", + } + for key in date_keys: + if key in json_data: + tai_datetime = get_tai_from_utc(json_data[key]) + json_data[key] = tai_datetime.strftime(DATETIME_ISO_FORMAT) + array_keys = { "components", "primary_software_components", diff --git a/manager/manager/utils.py b/manager/manager/utils.py index b36ee1c3..da5689ca 100644 --- a/manager/manager/utils.py +++ b/manager/manager/utils.py @@ -45,6 +45,8 @@ PRIMARY_SOFTWARE_COMPONENTS_IDS = "customfield_10107" PRIMARY_HARDWARE_COMPONENTS_IDS = "customfield_10196" +DATETIME_ISO_FORMAT = "%Y-%m-%dT%H:%M:%S.%f" + class LocationPermission(BasePermission): """Permission class to check if the user is in the location whitelist.""" @@ -833,6 +835,22 @@ def get_tai_to_utc() -> float: return dt +def get_tai_from_utc(utc): + """Return the TAI timestamp from an UTC timestamp. + + Parameters + ---------- + utc : `datetime.datetime` + UTC timestamp + + Returns + ------- + `datetime.datetime` + The TAI timestamp + """ + return Time(utc, scale="utc").tai.datetime + + def get_times(): """Return relevant time measures.