1616"""Test basic event consumption"""
1717
1818import html
19+ import json
1920from hashlib import sha256
2021from typing import cast
2122
2223import pytest
24+ from hexkit .correlation import correlation_id_var
2325
2426from ns .adapters .outbound .smtp_client import SmtpClient
2527from ns .core .models import NotificationRecord
3032
3133pytestmark = pytest .mark .asyncio ()
3234
35+ TEST_CORRELATION_ID = "6914c8cd-1f18-43da-ac6c-c43cca3f36cc"
36+
3337sample_notification = {
3438 "recipient_email" : "test@example.com" ,
3539 "email_cc" : ["test2@test.com" , "test3@test.com" ],
4044}
4145
4246
47+ @pytest .fixture (autouse = True )
48+ def correlation_id_fixture ():
49+ """Provides a new correlation ID for each test case."""
50+ # we cannot use an async fixture with set_correlation_id(),
51+ # because it would run in a different context from the test
52+ token = correlation_id_var .set (TEST_CORRELATION_ID )
53+ yield
54+ correlation_id_var .reset (token )
55+
56+
4357@pytest .mark .parametrize (
4458 "notification_details" ,
4559 [sample_notification ],
@@ -61,7 +75,7 @@ async def test_email_construction(
6175 plaintext_body = msg .get_body (preferencelist = "plain" )
6276 assert plaintext_body is not None
6377
64- plaintext_content = plaintext_body .get_content () # type: ignore
78+ plaintext_content = plaintext_body .get_content ()
6579 expected_plaintext = (
6680 "Dear Yolanda Martinez,\n \n Where are you, where are you, Yolanda?\n "
6781 + "\n Warm regards,\n \n The GHGA Team"
@@ -71,7 +85,7 @@ async def test_email_construction(
7185 html_body = msg .get_body (preferencelist = "html" )
7286 assert html_body is not None
7387
74- html_content = html_body .get_content () # type: ignore
88+ html_content = html_body .get_content ()
7589 assert html_content is not None
7690
7791 expected_html = (
@@ -149,9 +163,11 @@ async def test_helper_functions(joint_fixture: JointFixture):
149163 notification = make_notification (sample_notification )
150164
151165 # manually create a NotificationRecord for the notification
166+ concatenated = TEST_CORRELATION_ID + json .dumps (
167+ notification .model_dump (), sort_keys = True
168+ )
152169 expected_record = NotificationRecord (
153- hash_sum = sha256 (notification .model_dump_json ().encode ("utf-8" )).hexdigest (),
154- sent = False ,
170+ hash_sum = sha256 (concatenated .encode ("utf-8" )).hexdigest (), sent = False
155171 )
156172
157173 # Now create the record using the notifier's function and compare
@@ -198,6 +214,7 @@ async def test_idempotence_and_transmission(joint_fixture: JointFixture):
198214 joint_fixture .notifier = cast (Notifier , joint_fixture .notifier )
199215
200216 notification_event = make_notification (sample_notification )
217+
201218 await joint_fixture .kafka .publish_event (
202219 payload = notification_event .model_dump (),
203220 type_ = joint_fixture .config .notification_event_type ,
@@ -209,6 +226,12 @@ async def test_idempotence_and_transmission(joint_fixture: JointFixture):
209226 notification = notification_event
210227 )
211228
229+ # verify the hash is generated with the keys sorted and correlation ID prepended
230+ concatenated = TEST_CORRELATION_ID + json .dumps (
231+ notification_event .model_dump (), sort_keys = True
232+ )
233+ assert record .hash_sum == sha256 (concatenated .encode ("utf-8" )).hexdigest ()
234+
212235 # the record hasn't been sent, so this should return False
213236 assert not await joint_fixture .notifier ._has_been_sent (hash_sum = record .hash_sum )
214237
@@ -267,7 +290,7 @@ async def test_html_escaping(joint_fixture: JointFixture):
267290 plaintext_body = msg .get_body (preferencelist = "plain" )
268291 assert plaintext_body is not None
269292
270- plaintext_content = plaintext_body .get_content () # type: ignore
293+ plaintext_content = plaintext_body .get_content ()
271294 expected_plaintext = (
272295 f"Dear { original_name } ,\n \n { original_body } \n "
273296 + "\n Warm regards,\n \n The GHGA Team"
@@ -277,7 +300,7 @@ async def test_html_escaping(joint_fixture: JointFixture):
277300 html_body = msg .get_body (preferencelist = "html" )
278301 assert html_body is not None
279302
280- html_content = html_body .get_content () # type: ignore
303+ html_content = html_body .get_content ()
281304 assert html_content is not None
282305
283306 expected_html = (
0 commit comments