Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/run-e2e-automation-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ on:
- sandbox
- proxy_smoke
- Batch_File_Validation_Feature
mns_validation_required:
description: Set to true if you want the MNS validation to be performed as part of the tests. please keep in mind it will increase execution time.
default: "false"
type: boolean

env:
APIGEE_AUTH_ENV: ${{ inputs.apigee_environment == 'int' && inputs.apigee_environment || 'internal-dev' }}
Expand Down Expand Up @@ -235,6 +239,7 @@ jobs:
MEDICUS_client_Id: ${{ secrets.MEDICUS_client_Id }}
MEDICUS_client_Secret: ${{ secrets.MEDICUS_client_Secret }}
aws_account_id: ${{ vars.AWS_ACCOUNT_ID }}
mns_validation_required: ${{ inputs.mns_validation_required || startsWith(inputs.sub_environment, 'pr-') || inputs.apigee_environment == 'internal-dev' }}
TEST_PATH: ${{ inputs.service_under_test == 'batch' && 'features/batchTests' || inputs.service_under_test == 'fhir_api' && 'features/APITests' || 'features' }}
TEST_FILTER: ${{ inputs.suite_to_run == 'proxy_smoke' && 'Status_feature' || inputs.suite_to_run }}
run: poetry run pytest "$TEST_PATH" -m "$TEST_FILTER" --junitxml=output/test-results.xml --alluredir=output/allure-results
Expand Down
102 changes: 63 additions & 39 deletions tests/e2e_automation/features/APITests/steps/common_steps.py
Original file line number Diff line number Diff line change
Expand Up @@ -351,8 +351,10 @@ def send_update_for_immunization_event(context):
def created_event_is_being_updated_twice(context):
send_update_for_immunization_event(context)
The_request_will_have_status_code(context, 200)
mns_event_will_be_triggered_with_correct_data(context=context, action="UPDATE")
send_update_for_vaccination_detail(context)
The_request_will_have_status_code(context, 200)
mns_event_will_be_triggered_with_correct_data(context=context, action="UPDATE")


@given("created event is being deleted")
Expand All @@ -379,9 +381,8 @@ def mns_event_will_not_be_triggered_for_the_event(context):
message_body = read_message(
context,
queue_type="notification",
action="CREATE",
wait_time_seconds=5,
max_empty_polls=1,
max_total_wait_seconds=20,
)
print("No MNS create event is created")
assert message_body is None, "Not expected a message but queue returned a message"
Expand All @@ -392,9 +393,8 @@ def validate_mns_event_not_triggered_for_updated_event(context):
message_body = read_message(
context,
queue_type="notification",
action="UPDATE",
wait_time_seconds=5,
max_empty_polls=3,
max_total_wait_seconds=20,
)
print("no MNS update event is created")
assert message_body is None, "Not expected a message but queue returned a message"
Expand All @@ -417,14 +417,23 @@ def normalize_param(value: str) -> str:


def calculate_age(birth_date_str: str, occurrence_datetime_str: str) -> int:
birth = datetime.strptime(birth_date_str, "%Y-%m-%d").date()
birth = parse_birth_date(birth_date_str)
occurrence = datetime.fromisoformat(occurrence_datetime_str).date()
age = occurrence.year - birth.year
if (occurrence.month, occurrence.day) < (birth.month, birth.day):
age -= 1
return age


def parse_birth_date(date_str: str) -> datetime.date:
for fmt in ("%Y-%m-%d", "%Y%m%d"):
try:
return datetime.strptime(date_str, fmt).date()
except ValueError:
pass
raise ValueError(f"Invalid birth date format: {date_str}")


def is_valid_uuid(value: str) -> bool:
try:
uuid.UUID(value)
Expand Down Expand Up @@ -462,62 +471,77 @@ def validate_sqs_message(context, message_body, action):
f"msn event for {action} DataRef mismatch: expected {context.url}/{context.ImmsID}, got {message_body.dataref}",
)

check.is_true(
normalize(message_body.filtering.generalpractitioner) == normalize(context.gp_code),
f"msn event for {action} GP code mismatch: expected {context.gp_code}, got {message_body.filtering.generalpractitioner}",
)
if context.S3_env not in ["int", "preprod"]:
check.is_true(
message_body.filtering is not None,
f"msn event for {action} Filtering is missing in the message body",
)

expected_org = context.create_object.performer[1].actor.identifier.value
check.is_true(
normalize(message_body.filtering.sourceorganisation) == normalize(expected_org),
f"msn event for {action} Source org mismatch: expected {expected_org}, got {message_body.filtering.sourceorganisation}",
)
check.is_true(
normalize(message_body.filtering.generalpractitioner) == normalize(context.gp_code),
f"msn event for {action} GP code mismatch: expected {context.gp_code}, got {message_body.filtering.generalpractitioner}",
)

check.is_true(
message_body.filtering.sourceapplication.upper() == context.supplier_name.upper(),
f"msn event for {action} Source application mismatch: expected {context.supplier_name}, got {message_body.filtering.sourceapplication}",
)
expected_org = context.immunization_object.performer[1].actor.identifier.value
check.is_true(
normalize(message_body.filtering.sourceorganisation) == normalize(expected_org),
f"msn event for {action} Source org mismatch: expected {expected_org}, got {message_body.filtering.sourceorganisation}",
)

check.is_true(
message_body.filtering.subjectage == context.patient_age,
f"msn event for {action} Age mismatch: expected {context.patient_age}, got {message_body.filtering.subjectage}",
)
check.is_true(
message_body.filtering.sourceapplication.upper() == context.supplier_name.upper(),
f"msn event for {action} Source application mismatch: expected {context.supplier_name}, got {message_body.filtering.sourceapplication}",
)

check.is_true(
message_body.filtering.immunisationtype == context.vaccine_type.upper(),
f"msn event for {action} Immunisation type mismatch: expected {context.vaccine_type.upper()}, got {message_body.filtering.immunisationtype}",
)
check.is_true(
message_body.filtering.subjectage == context.patient_age,
f"msn event for {action} Age mismatch: expected {context.patient_age}, got {message_body.filtering.subjectage}",
)

check.is_true(
message_body.filtering.action == action.upper(),
f"msn event for {action} Action mismatch: expected {action.upper()}, got {message_body.filtering.action}",
)
check.is_true(
message_body.filtering.immunisationtype == context.vaccine_type.upper(),
f"msn event for {action} Immunisation type mismatch: expected {context.vaccine_type.upper()}, got {message_body.filtering.immunisationtype}",
)

check.is_true(
message_body.filtering.action == action.upper(),
f"msn event for {action} Action mismatch: expected {action.upper()}, got {message_body.filtering.action}",
)
else:
check.is_true(
message_body.filtering is None,
f"msn event for {action} Filtering is present in the message body when it shouldn't be for int environment",
)


def mns_event_will_be_triggered_with_correct_data_for_deleted_event(context):
if context.patient.identifier[0].value is None:
message_body = read_message(
context,
queue_type="notification",
action="DELETE",
wait_time_seconds=5,
max_empty_polls=3,
max_total_wait_seconds=20,
)
print(
"No MNS delete event is created as expected since NHS number is not present in the original immunization event"
)
assert message_body is None, "Not expected a message but queue returned a message"
else:
message_body = read_message(context, queue_type="notification", action="DELETE")
message_body = read_message(context, queue_type="notification")
print(f"Read deleted message from SQS: {message_body}")
assert message_body is not None, "Expected a delete message but queue returned empty"
validate_sqs_message(context, message_body, "DELETE")


def mns_event_will_be_triggered_with_correct_data(context, action):
message_body = read_message(context, queue_type="notification", action=action)
print(f"Read {action}d message from SQS: {message_body}")
assert message_body is not None, f"Expected a {action} message but queue returned empty"
context.gp_code = get_gp_code_by_nhs_number(context.patient.identifier[0].value)
context.patient_age = calculate_age(context.patient.birthDate, context.immunization_object.occurrenceDateTime)
validate_sqs_message(context, message_body, action)
if context.mns_validation_required.strip().lower() == "true":
message_body = read_message(context, queue_type="notification")
print(f"Read {action}d message from SQS: {message_body}")
assert message_body is not None, f"Expected a {action} message but queue returned empty"
context.gp_code = get_gp_code_by_nhs_number(context.patient.identifier[0].value)
context.patient_age = calculate_age(context.patient.birthDate, context.immunization_object.occurrenceDateTime)
validate_sqs_message(context, message_body, action)
else:
print(
f"MNS event validation is skipped since mns_validation_required is set to {context.mns_validation_required}"
)
Loading
Loading