Skip to content
Merged
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
2 changes: 1 addition & 1 deletion tests/e2e_automation/features/APITests/create.feature
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ Feature: Create the immunization event for a patient

@smoke
@Delete_cleanUp @supplier_name_TPP @vaccine_type_BCG @patient_id_Random
Scenario: Verify that the POST Create API will fail when exiting Unique Id and no_unique_id_uri is used in the request
Scenario: Verify that the POST Create API will fail when exiting Unique Id and unique_id_uri is used in the request
Given Valid json payload is created
When Trigger the post create request
Then The request will be successful with the status code '201'
Expand Down
95 changes: 94 additions & 1 deletion tests/e2e_automation/features/APITests/delete.feature
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,97 @@ Feature: Delete an immunization of a patient
And The delta table will be populated with the correct data for deleted event
When same delete request is triggered again
Then The request will be unsuccessful with the status code '404'
And The Response JSONs should contain correct error message for Imms_id 'not_found'
And The Response JSONs should contain correct error message for Imms_id 'not_found'


@vaccine_type_HEPB @patient_id_Random @supplier_name_TPP
Scenario: Verify that the create request will be reinstated successfully after the record is soft deleted
Given I have created a valid vaccination record
When Send a delete for Immunization event created
Then The request will be successful with the status code '204'
And IMMS event and delta tables, along with the MNS event, will be populated with correct data for the deleted record
When Trigger another post create request with same unique_id and unique_id_uri
Then The request will be successful with the status code '201'
And The location key and Etag in header will contain the previous Immunization Id and version will be incremented by 1
And IMMS event and delta tables, along with the MNS event, will be populated with correct created data for the reinstated record
When Send a delete for Immunization event created
Then The request will be successful with the status code '204'
And IMMS event and delta tables, along with the MNS event, will be populated with correct data for the deleted record


@vaccine_type_6IN1 @patient_id_Random @supplier_name_TPP
Scenario: Verify that the update request is reinstated successfully after the record is soft deleted
Given I have created a valid vaccination record
When Send a delete for Immunization event created
Then The request will be successful with the status code '204'
And IMMS event and delta tables, along with the MNS event, will be populated with correct data for the deleted record
When Trigger update request with same unique_id and unique_id_uri for the deleted record
Then The request will be successful with the status code '200'
And The Etag in header will contain the correct version which will be incremented by 1
And IMMS event and delta tables, along with the MNS event, will be populated with correct updated data for the reinstated record
When Send a delete for Immunization event created
Then The request will be successful with the status code '204'
And IMMS event and delta tables, along with the MNS event, will be populated with correct data for the deleted record

@vaccine_type_HEPB @patient_id_Random @supplier_name_TPP
Scenario: Verify that the identifier search request will have empty response for deleted record
Given I have created a valid vaccination record
When Send a delete for Immunization event created
Then The request will be successful with the status code '204'
And IMMS event and delta tables, along with the MNS event, will be populated with correct data for the deleted record
When I send a search request with Post method using identifier parameter for the record
Then The request will be successful with the status code '200'
#And No immunization event is returned in the response - defect need fixing for this VED-1263

@vaccine_type_HEPB @patient_id_Random @supplier_name_TPP
Scenario: Verify that the search request will have empty response for deleted record
Given I have created a valid vaccination record
When Send a delete for Immunization event created
Then The request will be successful with the status code '204'
And IMMS event and delta tables, along with the MNS event, will be populated with correct data for the deleted record
When Send a search request with post method using patient.identifier and target-disease for Immunization event deleted
Then The request will be successful with the status code '200'
And No immunization event is returned in the response

@Delete_cleanUp @vaccine_type_HEPB @patient_id_Random @supplier_name_TPP
Scenario: Verify that the search request will be successful for reinstated record with create operation
Given I have created a valid vaccination record
When Send a delete for Immunization event created
Then The request will be successful with the status code '204'
And IMMS event and delta tables, along with the MNS event, will be populated with correct data for the deleted record
When Trigger another post create request with same unique_id and unique_id_uri
Then The request will be successful with the status code '201'
And The location key and Etag in header will contain the previous Immunization Id and version will be incremented by 1
And IMMS event and delta tables, along with the MNS event, will be populated with correct created data for the reinstated record
When I send a search request with Post method using identifier parameter for the record
Then The request will be successful with the status code '200'
And reinstated record is returned in the response with correct created data


@Delete_cleanUp @vaccine_type_6IN1 @patient_id_Random @supplier_name_TPP
Scenario: Verify that the search request will be successful for reinstated record with update operation
Given I have created a valid vaccination record
When Send a delete for Immunization event created
Then The request will be successful with the status code '204'
And IMMS event and delta tables, along with the MNS event, will be populated with correct data for the deleted record
When Trigger update request with same unique_id and unique_id_uri for the deleted record
Then The request will be successful with the status code '200'
And The Etag in header will contain the correct version which will be incremented by 1
And IMMS event and delta tables, along with the MNS event, will be populated with correct updated data for the reinstated record
When I send a search request with Post method using identifier parameter for the record
Then The request will be successful with the status code '200'
And reinstated record is returned in the response with correct created data

@Delete_cleanUp @vaccine_type_HEPB @patient_id_Random @supplier_name_TPP
Scenario: Verify that the create request will be unsuccessfully for already reinstated record
Given I have created a valid vaccination record
When Send a delete for Immunization event created
Then The request will be successful with the status code '204'
And IMMS event and delta tables, along with the MNS event, will be populated with correct data for the deleted record
When Trigger another post create request with same unique_id and unique_id_uri
Then The request will be successful with the status code '201'
And The location key and Etag in header will contain the previous Immunization Id and version will be incremented by 1
And IMMS event and delta tables, along with the MNS event, will be populated with correct created data for the reinstated record
When Trigger another post create request with same unique_id and unique_id_uri
Then The request will be unsuccessful with the status code '422'
And The Response JSONs should contain correct error message for 'duplicate'
107 changes: 84 additions & 23 deletions tests/e2e_automation/features/APITests/steps/common_steps.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@
import uuid
from datetime import UTC, datetime, timedelta
from urllib.parse import parse_qs
from venv import logger

import pytest_check as check
from pytest_bdd import given, parsers, then, when
Comment thread
FimranNHS marked this conversation as resolved.
from src.dynamoDB.dynamo_db_helper import (
fetch_immunization_events_detail,
fetch_immunization_int_delta_detail_by_immsID,
parse_imms_int_imms_event_response,
validate_imms_delta_record_with_created_event,
)
from src.objectModels.api_immunization_builder import (
build_site_route,
Expand Down Expand Up @@ -38,7 +39,7 @@
get_update_url_header,
)
from utilities.date_helper import is_valid_date, normalize_utc_suffix
from utilities.enums import Operation
from utilities.enums import ActionFlag, Operation
from utilities.http_requests_session import http_requests_session
from utilities.sqs_message_halder import read_message
from utilities.vaccination_constants import ROUTE_MAP, SITE_MAP
Expand Down Expand Up @@ -168,15 +169,16 @@ def The_request_will_have_status_code(context, statusCode):

@then("The location key and Etag in header will contain the Immunization Id and version")
def validateCreateLocation(context):
location = context.response.headers["location"]
eTag = context.response.headers["E-Tag"]
body = get_response_body_for_display(context.response)
assert "location" in context.response.headers, (
f"Location header is missing in the response with Status code: {context.response.status_code}. Response: {body}"
)
assert "E-Tag" in context.response.headers, (
f"E-Tag header is missing in the response with Status code: {context.response.status_code}. Response: {body}"
)
location = context.response.headers["location"]
eTag = context.response.headers["E-Tag"]

context.ImmsID = location.split("/")[-1]
context.eTag = eTag.strip('"')
print(f"\n Immunization ID is {context.ImmsID} and Etag is {context.eTag} \n")
Expand Down Expand Up @@ -254,7 +256,7 @@ def validateCreateHeader(context):


@then(parsers.parse("The imms event table will be populated with the correct data for '{operation}' event"))
def validate_imms_event_table_by_operation(context, operation: Operation):
def validate_imms_event_table_by_operation(context, operation: Operation, reinstated=False):
create_obj = context.create_object
table_query_response = fetch_immunization_events_detail(context.aws_profile_name, context.ImmsID, context.S3_env)
assert "Item" in table_query_response, f"Item not found in response for ImmsID: {context.ImmsID}"
Expand All @@ -265,8 +267,7 @@ def validate_imms_event_table_by_operation(context, operation: Operation):

try:
resource = json.loads(resource_json_str)
except (TypeError, json.JSONDecodeError) as e:
logger.error(f"Failed to parse Resource from item: {e}")
except (TypeError, json.JSONDecodeError):
raise AssertionError("Failed to parse Resource from response item.")

assert resource is not None, "Resource is None in the response"
Expand All @@ -275,7 +276,7 @@ def validate_imms_event_table_by_operation(context, operation: Operation):
assert int(context.expected_version) == int(context.eTag), (
f"Expected Version: {context.expected_version}, Found: {context.eTag}"
)

actualDeletedAt = item.get("DeletedAt")
fields_to_compare = [
("Operation", Operation[operation].value, item.get("Operation")),
(
Expand All @@ -299,6 +300,22 @@ def validate_imms_event_table_by_operation(context, operation: Operation):
for name, expected, actual in fields_to_compare:
check.is_true(expected == actual, f"Expected {name}: {expected}, Actual {actual}")

if Operation[operation].value == "DELETE":
check.is_true(
actualDeletedAt is not None and actualDeletedAt > 0,
f"Expected DeletedAt to be a Unix timestamp, got {actualDeletedAt}",
)
elif reinstated:
check.is_true(
actualDeletedAt == "reinstated",
f"Expected DeletedAt: None for reinstated record, got {actualDeletedAt}",
)
else:
check.is_true(
actualDeletedAt is None,
f"Expected DeletedAt: None, Actual {actualDeletedAt}",
)

validate_to_compare_request_and_response(context, create_obj, created_event, True)


Expand Down Expand Up @@ -401,6 +418,40 @@ def validate_mns_event_not_triggered_for_updated_event(context):
mns_event_will_not_be_triggered_for_the_event(context)


@when("Trigger another post create request with same unique_id and unique_id_uri")
def trigger_post_create_with_same_unique_id(context):
Comment thread
FimranNHS marked this conversation as resolved.
context.immunization_object.contained[1].address[0].city = "Updated City"
context.immunization_object.contained[1].address[0].state = "Updated State"
Trigger_the_post_create_request(context)


@then("The delta table will be populated with the correct data for updated event")
def validate_delta_table_for_updated_event(context):
create_obj = context.create_object
items = fetch_immunization_int_delta_detail_by_immsID(
context.aws_profile_name,
context.ImmsID,
context.S3_env,
context.expected_version,
)
assert items, f"Items not found in response for ImmsID: {context.ImmsID}"
delta_items = [i for i in items if i.get("Operation") == Operation.updated.value]
assert delta_items, f"No item found for ImmsID: {context.ImmsID}"
latest_delta_record = max(delta_items, key=lambda x: x.get("SequenceNumber", -1))
validate_imms_delta_record_with_created_event(
context,
create_obj,
latest_delta_record,
Operation.updated.value,
ActionFlag.updated.value,
)


@then("MNS event will be triggered with correct data for Updated event")
def validate_mns_event_triggered_for_updated_event(context):
mns_event_will_be_triggered_with_correct_data(context=context, action="UPDATE")


def trigger_the_updated_request(context):
context.expected_version = int(context.expected_version) + 1
context.create_object = context.update_object
Expand Down Expand Up @@ -518,22 +569,25 @@ def validate_sqs_message(context, message_body, action):


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",
wait_time_seconds=5,
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"
if context.mns_validation_required.strip().lower() == "true":
if context.patient.identifier[0].value is None:
message_body = read_message(
context,
queue_type="notification",
wait_time_seconds=5,
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")
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")
else:
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")
print("MNS validation not required, skipping MNS event verification for deleted event.")


def mns_event_will_be_triggered_with_correct_data(context, action):
Expand All @@ -553,3 +607,10 @@ def mns_event_will_be_triggered_with_correct_data(context, action):
print(
f"MNS event validation is skipped since mns_validation_required is set to {context.mns_validation_required}"
)


def trigger_update_request_with_same_unique_id_and_uri_for_deleted_record(context):
get_update_url_header(context, str(context.expected_version))
context.update_object = copy.deepcopy(context.immunization_object)
context.update_object = convert_to_update(context.update_object, context.ImmsID)
trigger_the_updated_request(context)
17 changes: 5 additions & 12 deletions tests/e2e_automation/features/APITests/steps/test_create_steps.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import json
import random
from datetime import UTC, datetime, timedelta
from venv import logger

import pytest_check as check
from pytest_bdd import given, parsers, scenarios, then, when
from pytest_bdd import given, parsers, scenarios, then
from src.dynamoDB.dynamo_db_helper import (
fetch_immunization_events_detail,
fetch_immunization_int_delta_detail_by_immsID,
Expand Down Expand Up @@ -34,7 +33,7 @@
VACCINE_CODE_MAP,
)

from .common_steps import Trigger_the_post_create_request, valid_json_payload_is_created
from .common_steps import valid_json_payload_is_created

scenarios("APITests/create.feature")

Expand Down Expand Up @@ -242,8 +241,7 @@ def validate_imms_event_table(context):

try:
resource = json.loads(resource_json_str)
except (TypeError, json.JSONDecodeError) as e:
logger.error(f"Failed to parse Resource from item: {e}")
except (TypeError, json.JSONDecodeError):
raise AssertionError("Failed to parse Resource from response item.")

assert resource is not None, "Resource is None in the response"
Expand Down Expand Up @@ -347,8 +345,8 @@ def validate_procedure_term_correct_coding_in_delta_table(context):
@then("The delta table will use the first valid SNOMED site and route coding")
def validate_delta_table_uses_first_valid_snomed_site_route_coding(context):
actual_terms = get_all_term_text(context)
expected_site_term = context.create_object.site.coding[1].extension[0].valueString
expected_route_term = context.create_object.route.coding[1].extension[0].valueString
expected_site_term = context.create_object.site.text
expected_route_term = context.create_object.route.text
assert actual_terms["site_term"] == expected_site_term, (
f"Expected site of vaccination term '{expected_site_term}', but got '{actual_terms['site_term']}'"
)
Expand Down Expand Up @@ -449,8 +447,3 @@ def create_request_with_invalid_gender(context, gender):
def create_request_with_empty_nam(context):
valid_json_payload_is_created(context)
context.immunization_object.contained[1].name = None


@when("Trigger another post create request with same unique_id and unique_id_uri")
def trigger_post_create_with_same_unique_id(context):
Trigger_the_post_create_request(context)
Loading
Loading