diff --git a/src/nos/core/notifications.py b/src/nos/core/notifications.py index d0c3ad2..a68b82e 100644 --- a/src/nos/core/notifications.py +++ b/src/nos/core/notifications.py @@ -136,7 +136,11 @@ def formatted(self, **kwargs) -> "Notification": ALL_IVAS_INVALIDATED_TO_USER = Notification( "IVA Invalidation", - "All of your IVAs have been successfully invalidated.", + """ +All of your IVAs have been successfully invalidated. + +If you have any questions, please contact a Data Steward at GHGA: {email}. +""", ) IVA_CODE_REQUESTED_TO_USER = Notification( diff --git a/src/nos/core/orchestrator.py b/src/nos/core/orchestrator.py index 1abf019..ce53d4b 100644 --- a/src/nos/core/orchestrator.py +++ b/src/nos/core/orchestrator.py @@ -248,7 +248,7 @@ async def _iva_unverified( ), ) - async def process_all_ivas_reset(self, *, user_id: str): + async def process_all_ivas_invalidated(self, *, user_id: str): """Send a notification to the user when all their IVAs are reset.""" try: user = await self._user_dao.get_by_id(user_id) @@ -265,7 +265,9 @@ async def process_all_ivas_reset(self, *, user_id: str): await self._notification_emitter.notify( email=user.email, full_name=user.name, - notification=notifications.ALL_IVAS_INVALIDATED_TO_USER, + notification=notifications.ALL_IVAS_INVALIDATED_TO_USER.formatted( + email=self._config.central_data_stewardship_email + ), ) async def process_iva_state_change(self, *, user_iva: event_schemas.UserIvaState): diff --git a/src/nos/ports/inbound/orchestrator.py b/src/nos/ports/inbound/orchestrator.py index 76bfabb..ca221c8 100644 --- a/src/nos/ports/inbound/orchestrator.py +++ b/src/nos/ports/inbound/orchestrator.py @@ -53,7 +53,7 @@ async def process_file_registered_notification(self, *, file_id: str): """Send notifications for internal file registrations (completed uploads).""" @abstractmethod - async def process_all_ivas_reset(self, *, user_id: str): + async def process_all_ivas_invalidated(self, *, user_id: str): """Handle notifications for all IVA resets.""" @abstractmethod diff --git a/src/nos/translators/inbound/event_sub.py b/src/nos/translators/inbound/event_sub.py index bd08cb3..52c87c6 100644 --- a/src/nos/translators/inbound/event_sub.py +++ b/src/nos/translators/inbound/event_sub.py @@ -119,7 +119,7 @@ async def _handle_iva_state_change(self, payload: JsonObject) -> None: async def _handle_all_ivas_reset(self, payload: JsonObject) -> None: """Send notifications for all IVA resets.""" validated_payload = get_validated_payload(payload, event_schemas.UserIvaState) - await self._orchestrator.process_all_ivas_reset( + await self._orchestrator.process_all_ivas_invalidated( user_id=validated_payload.user_id ) diff --git a/tests/test_orchestrator.py b/tests/test_orchestrator.py index f50975d..dfced89 100644 --- a/tests/test_orchestrator.py +++ b/tests/test_orchestrator.py @@ -326,3 +326,48 @@ async def test_iva_state_change( in_topic=joint_fixture.config.notification_event_topic, ): await joint_fixture.event_subscriber.run(forever=False) + + +@pytest.mark.asyncio(scope="module") +async def test_all_ivas_reset(joint_fixture: JointFixture): + """Test that the 'all IVA invalidated' events are translated into a notification.""" + # Prepare triggering event (the IVA state change event). + trigger_event = event_schemas.UserIvaState( + user_id=TEST_USER.id, + state=event_schemas.IvaState.UNVERIFIED, + value=None, + type=None, + ) + + # Publish the trigger event + await joint_fixture.kafka.publish_event( + payload=trigger_event.model_dump(), + type_=joint_fixture.config.iva_state_changed_event_type, + topic=joint_fixture.config.iva_events_topic, + key=f"all-{TEST_USER.id}", + ) + + # Define the event that should be published by the NOS when the trigger is consumed + ds_email = joint_fixture.config.central_data_stewardship_email + expected_notification = event_schemas.Notification( + recipient_email=TEST_USER.email, + recipient_name=TEST_USER.name, + subject="IVA Invalidation", + plaintext_body=f""" +All of your IVAs have been successfully invalidated. + +If you have any questions, please contact a Data Steward at GHGA: {ds_email}. +""", + ) + + expected_event = ExpectedEvent( + payload=expected_notification.model_dump(), + type_=joint_fixture.config.notification_event_type, + ) + + # consume the event and verify that the expected event is published + async with joint_fixture.kafka.expect_events( + events=[expected_event], + in_topic=joint_fixture.config.notification_event_topic, + ): + await joint_fixture.event_subscriber.run(forever=False)