diff --git a/tests/e2e_automation/features/APITests/create.feature b/tests/e2e_automation/features/APITests/create.feature index 877dd873d..e83b26674 100644 --- a/tests/e2e_automation/features/APITests/create.feature +++ b/tests/e2e_automation/features/APITests/create.feature @@ -280,7 +280,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' diff --git a/tests/e2e_automation/features/APITests/delete.feature b/tests/e2e_automation/features/APITests/delete.feature index 1cd6a6d91..0b8a1c1f3 100644 --- a/tests/e2e_automation/features/APITests/delete.feature +++ b/tests/e2e_automation/features/APITests/delete.feature @@ -48,4 +48,73 @@ 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' \ No newline at end of file + 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 create 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 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 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 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 + + @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 + + + @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 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 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 \ No newline at end of file diff --git a/tests/e2e_automation/features/APITests/steps/common_steps.py b/tests/e2e_automation/features/APITests/steps/common_steps.py index 46ac77285..4d781fc2b 100644 --- a/tests/e2e_automation/features/APITests/steps/common_steps.py +++ b/tests/e2e_automation/features/APITests/steps/common_steps.py @@ -10,7 +10,9 @@ from pytest_bdd import given, parsers, then, when 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, @@ -38,7 +40,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 @@ -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}" @@ -275,7 +277,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")), ( @@ -299,6 +301,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( + isinstance(actualDeletedAt, int) 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) @@ -401,6 +419,38 @@ 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): + 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 @@ -553,3 +603,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) diff --git a/tests/e2e_automation/features/APITests/steps/test_create_steps.py b/tests/e2e_automation/features/APITests/steps/test_create_steps.py index 2ceeaf2fe..3044ee63f 100644 --- a/tests/e2e_automation/features/APITests/steps/test_create_steps.py +++ b/tests/e2e_automation/features/APITests/steps/test_create_steps.py @@ -4,7 +4,7 @@ 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, @@ -32,7 +32,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") @@ -341,8 +341,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) diff --git a/tests/e2e_automation/features/APITests/steps/test_delete_steps.py b/tests/e2e_automation/features/APITests/steps/test_delete_steps.py index f9deed5f2..73a5f13df 100644 --- a/tests/e2e_automation/features/APITests/steps/test_delete_steps.py +++ b/tests/e2e_automation/features/APITests/steps/test_delete_steps.py @@ -1,11 +1,14 @@ +import copy import logging import uuid from pytest_bdd import parsers, scenarios, then, when +from pytest_check.context_manager import check from src.dynamoDB.dynamo_db_helper import ( fetch_immunization_int_delta_detail_by_immsID, validate_imms_delta_record_with_created_event, ) +from src.objectModels.api_immunization_builder import convert_to_update from utilities.api_fhir_immunization_helper import ( find_entry_by_Imms_id, parse_FHIR_immunization_response, @@ -16,10 +19,20 @@ from .common_steps import ( The_request_will_have_status_code, + mns_event_will_be_triggered_with_correct_data_for_deleted_event, send_delete_for_immunization_event_created, + trigger_update_request_with_same_unique_id_and_uri_for_deleted_record, valid_token_is_generated, + validate_delta_table_for_updated_event, + validate_imms_event_table_by_operation, + validate_mns_event_triggered_for_updated_event, +) +from .test_search_steps import ( + send_search_post_request_with_identifier_and_elements_header, + trigger_search_request, + validate_correct_immunization_event, + validate_empty_immunization_event, ) -from .test_search_steps import trigger_search_request logging.basicConfig(filename="debugLog.log", level=logging.INFO) logger = logging.getLogger(__name__) @@ -48,12 +61,10 @@ def validate_imms_delta_table_by_deleted_ImmsID(context): items = fetch_immunization_int_delta_detail_by_immsID(context.aws_profile_name, context.ImmsID, context.S3_env, 2) assert items, f"Items not found in response for ImmsID: {context.ImmsID}" - # Find the latest item where operation is DELETE deleted_items = [i for i in items if i.get("Operation") == Operation.deleted.value] assert deleted_items, f"No deleted item found for ImmsID: {context.ImmsID}" - # Assuming each item has a 'timestamp' field to determine the latest - latest_delta_record = max(deleted_items, key=lambda x: x.get("timestamp", 0)) + latest_delta_record = max(deleted_items, key=lambda x: x.get("SequenceNumber", -1)) validate_imms_delta_record_with_created_event( context, @@ -92,3 +103,78 @@ def validate_deleted_immunization_event_not_present_using_post(context): assert context.created_event is None, ( f"Immunization event with ID {context.ImmsID} should not be present in the search response after deletion." ) + + +@then( + "The location key and Etag in header will contain the previous Immunization Id and version will be incremented by 1" +) +def validate_location_key_and_etag_in_header(context): + location = context.response.headers["location"] + eTag = context.response.headers["E-Tag"] + context.expected_version += 1 + assert "location" in context.response.headers, ( + f"Location header is missing in the response with Status code: {context.response.status_code}. Response: {context.response.text}" + ) + assert "E-Tag" in context.response.headers, ( + f"E-Tag header is missing in the response with Status code: {context.response.status_code}. Response: {context.response.text}" + ) + print(f"\n Immunization ID is {context.ImmsID} and Etag is {context.eTag} \n") + actualLocation = location.split("/")[-1] + check.is_true( + context.ImmsID == actualLocation, + f"Expected imms id sholud be : {context.ImmsID}, Found: {actualLocation}", + ) + check.is_true( + str(context.expected_version) == eTag.strip('"'), + f"Expected version should be : {context.expected_version}, Found: {eTag}", + ) + context.eTag = eTag.strip('"') + + +@then( + "IMMS event and delta tables, along with the MNS event, will be populated with correct created data for the reinstated record" +) +def validate_delta_table_for_create_event_for_reinstated_record(context): + context.update_object = copy.deepcopy(context.immunization_object) + context.update_object = convert_to_update(context.update_object, context.ImmsID) + validate_imms_event_table_by_operation(context, "created", reinstated=True) + validate_delta_table_for_updated_event(context) + validate_mns_event_triggered_for_updated_event(context) + + +@then( + "IMMS event and delta tables, along with the MNS event, will be populated with correct updated data for the reinstated record" +) +def validate_delta_table_for_updated_event_for_reinstated_record(context): + validate_imms_event_table_by_operation(context, "updated", reinstated=True) + validate_delta_table_for_updated_event(context) + validate_mns_event_triggered_for_updated_event(context) + + +@when("Trigger update request with same unique_id and unique_id_uri for the deleted record") +def trigger_post_create_request_with_same_unique_id_and_uri(context): + trigger_update_request_with_same_unique_id_and_uri_for_deleted_record(context) + + +@then( + "IMMS event and delta tables, along with the MNS event, will be populated with correct data for the deleted record" +) +def validate_imms_event_delta_and_mns_for_deleted_record(context): + validate_imms_event_table_by_operation(context, "deleted") + validate_imms_delta_table_by_deleted_ImmsID(context) + mns_event_will_be_triggered_with_correct_data_for_deleted_event(context) + + +@when("I send a search request with Post method using identifier parameter for the record") +def trigger_search_request_for_deleted_record(context): + send_search_post_request_with_identifier_and_elements_header(context) + + +@then("No immunization event is returned in the response") +def validate_no_immunization_event_returned_in_response(context): + validate_empty_immunization_event(context) + + +@then("reinstated record is returned in the response with correct created data") +def validate_reinstated_record_returned_in_response_with_correct_data(context): + validate_correct_immunization_event(context) diff --git a/tests/e2e_automation/features/APITests/steps/test_update_steps.py b/tests/e2e_automation/features/APITests/steps/test_update_steps.py index a757d5c5f..cfa82fd3e 100644 --- a/tests/e2e_automation/features/APITests/steps/test_update_steps.py +++ b/tests/e2e_automation/features/APITests/steps/test_update_steps.py @@ -2,10 +2,6 @@ import uuid from pytest_bdd import parsers, scenarios, then, when -from src.dynamoDB.dynamo_db_helper import ( - fetch_immunization_int_delta_detail_by_immsID, - validate_imms_delta_record_with_created_event, -) from src.objectModels.api_immunization_builder import convert_to_update from utilities.api_fhir_immunization_helper import ( parse_error_response, @@ -13,10 +9,8 @@ ) from utilities.api_get_header import get_update_url_header from utilities.date_helper import generate_date -from utilities.enums import ActionFlag, Operation from .common_steps import ( - mns_event_will_be_triggered_with_correct_data, send_update_for_immunization_event, trigger_the_updated_request, valid_json_payload_is_created, @@ -32,28 +26,6 @@ def send_update_for_immunization_event_by_supplier(context, Supplier): send_update_for_immunization_event(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, - ) - - @when( parsers.parse("Send a update for Immunization event created with occurrenceDateTime being updated to '{DateText}'") ) @@ -120,8 +92,3 @@ def validateForbiddenAccess(context, errorName): error_response = parse_error_response(context.response.json()) validate_error_response(error_response, errorName, version=context.version) print(f"\n Error Response - \n {error_response}") - - -@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") diff --git a/tests/e2e_automation/features/batchTests/Steps/test_update_batch_steps.py b/tests/e2e_automation/features/batchTests/Steps/test_update_batch_steps.py index 8ab8e4c42..fe2fb8a53 100644 --- a/tests/e2e_automation/features/batchTests/Steps/test_update_batch_steps.py +++ b/tests/e2e_automation/features/batchTests/Steps/test_update_batch_steps.py @@ -18,6 +18,7 @@ mns_event_will_be_triggered_with_correct_data, send_update_for_immunization_event, valid_json_payload_is_created, + validate_delta_table_for_updated_event, validate_etag_in_header, validate_imms_event_table_by_operation, validateCreateLocation, @@ -26,9 +27,6 @@ from features.APITests.steps.test_create_steps import ( validate_imms_delta_table_by_ImmsID, ) -from features.APITests.steps.test_update_steps import ( - validate_delta_table_for_updated_event, -) from .batch_common_steps import ( build_batch_row_from_api_object,