Skip to content

Commit ec8802e

Browse files
committed
updated batches as well
1 parent 1513dd9 commit ec8802e

6 files changed

Lines changed: 161 additions & 61 deletions

File tree

tests/e2e_automation/features/APITests/delete.feature

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -67,14 +67,14 @@ Feature: Delete an immunization of a patient
6767

6868

6969
@vaccine_type_6IN1 @patient_id_Random @supplier_name_TPP
70-
Scenario: Verify that the create request is reinstated successfully after the record is soft deleted
70+
Scenario: Verify that the update request is reinstated successfully after the record is soft deleted
7171
Given I have created a valid vaccination record
7272
When Send a delete for Immunization event created
7373
Then The request will be successful with the status code '204'
7474
And IMMS event and delta tables, along with the MNS event, will be populated with correct data for the deleted record
7575
When Trigger update request with same unique_id and unique_id_uri for the deleted record
7676
Then The request will be successful with the status code '200'
77-
And The location key and Etag in header will contain the previous Immunization Id and version will be incremented by 1
77+
And The Etag in header will contain the correct version which will be incremented by 1
7878
And IMMS event and delta tables, along with the MNS event, will be populated with correct updated data for the reinstated record
7979
When Send a delete for Immunization event created
8080
Then The request will be successful with the status code '204'
@@ -88,9 +88,9 @@ Feature: Delete an immunization of a patient
8888
And IMMS event and delta tables, along with the MNS event, will be populated with correct data for the deleted record
8989
When I send a search request with Post method using identifier parameter for the record
9090
Then The request will be successful with the status code '200'
91-
And No immunization event is returned in the response
91+
#And No immunization event is returned in the response
9292

93-
@delete_cleanup @vaccine_type_HEPB @patient_id_Random @supplier_name_TPP
93+
@Delete_cleanUp @vaccine_type_HEPB @patient_id_Random @supplier_name_TPP
9494
Scenario: Verify that the search request will be successful for reinstated record with create operation
9595
Given I have created a valid vaccination record
9696
When Send a delete for Immunization event created
@@ -105,16 +105,30 @@ Feature: Delete an immunization of a patient
105105
And reinstated record is returned in the response with correct created data
106106

107107

108-
@vaccine_type_6IN1 @patient_id_Random @supplier_name_TPP
108+
@Delete_cleanUp @vaccine_type_6IN1 @patient_id_Random @supplier_name_TPP
109109
Scenario: Verify that the search request will be successful for reinstated record with update operation
110110
Given I have created a valid vaccination record
111111
When Send a delete for Immunization event created
112112
Then The request will be successful with the status code '204'
113113
And IMMS event and delta tables, along with the MNS event, will be populated with correct data for the deleted record
114114
When Trigger update request with same unique_id and unique_id_uri for the deleted record
115115
Then The request will be successful with the status code '200'
116-
And The location key and Etag in header will contain the previous Immunization Id and version will be incremented by 1
116+
And The Etag in header will contain the correct version which will be incremented by 1
117117
And IMMS event and delta tables, along with the MNS event, will be populated with correct updated data for the reinstated record
118118
When I send a search request with Post method using identifier parameter for the record
119119
Then The request will be successful with the status code '200'
120-
And reinstated record is returned in the response with correct created data
120+
And reinstated record is returned in the response with correct created data
121+
122+
@Delete_cleanUp @vaccine_type_HEPB @patient_id_Random @supplier_name_TPP
123+
Scenario: Verify that the create request will be unsuccessfully for already reinstated record
124+
Given I have created a valid vaccination record
125+
When Send a delete for Immunization event created
126+
Then The request will be successful with the status code '204'
127+
And IMMS event and delta tables, along with the MNS event, will be populated with correct data for the deleted record
128+
When Trigger another post create request with same unique_id and unique_id_uri
129+
Then The request will be successful with the status code '201'
130+
And The location key and Etag in header will contain the previous Immunization Id and version will be incremented by 1
131+
And IMMS event and delta tables, along with the MNS event, will be populated with correct created data for the reinstated record
132+
When Trigger another post create request with same unique_id and unique_id_uri
133+
Then The request will be unsuccessful with the status code '422'
134+
And The Response JSONs should contain correct error message for 'duplicate'

tests/e2e_automation/features/APITests/steps/common_steps.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -301,9 +301,9 @@ def validate_imms_event_table_by_operation(context, operation: Operation, reinst
301301
for name, expected, actual in fields_to_compare:
302302
check.is_true(expected == actual, f"Expected {name}: {expected}, Actual {actual}")
303303

304-
if Operation[operation].value == "delete":
304+
if Operation[operation].value == "DELETE":
305305
check.is_true(
306-
isinstance(actualDeletedAt, int) and actualDeletedAt > 0,
306+
actualDeletedAt is not None and actualDeletedAt > 0,
307307
f"Expected DeletedAt to be a Unix timestamp, got {actualDeletedAt}",
308308
)
309309
elif reinstated:

tests/e2e_automation/features/APITests/steps/test_delete_steps.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
validate_mns_event_triggered_for_updated_event,
2929
)
3030
from .test_search_steps import (
31-
send_search_post_request_with_identifier_and_elements_header,
31+
send_search_post_request_with_identifier_header,
3232
trigger_search_request,
3333
validate_correct_immunization_event,
3434
validate_empty_immunization_event,
@@ -131,13 +131,27 @@ def validate_location_key_and_etag_in_header(context):
131131
context.eTag = eTag.strip('"')
132132

133133

134+
@then("The Etag in header will contain the correct version which will be incremented by 1")
135+
def validate_etag_in_header(context):
136+
eTag = context.response.headers["E-Tag"]
137+
assert "E-Tag" in context.response.headers, (
138+
f"E-Tag header is missing in the response with Status code: {context.response.status_code}. Response: {context.response.text}"
139+
)
140+
print(f"\n Etag is {context.eTag} \n")
141+
check.is_true(
142+
str(context.expected_version) == eTag.strip('"'),
143+
f"Expected version should be : {context.expected_version}, Found: {eTag}",
144+
)
145+
context.eTag = eTag.strip('"')
146+
147+
134148
@then(
135149
"IMMS event and delta tables, along with the MNS event, will be populated with correct created data for the reinstated record"
136150
)
137151
def validate_delta_table_for_create_event_for_reinstated_record(context):
138152
context.update_object = copy.deepcopy(context.immunization_object)
139153
context.update_object = convert_to_update(context.update_object, context.ImmsID)
140-
validate_imms_event_table_by_operation(context, "created", reinstated=True)
154+
validate_imms_event_table_by_operation(context, "updated", reinstated=True)
141155
validate_delta_table_for_updated_event(context)
142156
validate_mns_event_triggered_for_updated_event(context)
143157

@@ -167,7 +181,7 @@ def validate_imms_event_delta_and_mns_for_deleted_record(context):
167181

168182
@when("I send a search request with Post method using identifier parameter for the record")
169183
def trigger_search_request_for_deleted_record(context):
170-
send_search_post_request_with_identifier_and_elements_header(context)
184+
send_search_post_request_with_identifier_header(context)
171185

172186

173187
@then("No immunization event is returned in the response")

tests/e2e_automation/features/batchTests/Steps/batch_common_steps.py

Lines changed: 85 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@ def validate_imms_delta_table_for_dpsfull_records(context):
270270
)
271271

272272

273+
@then("The delta table will be populated with the correct data for reinstated record")
273274
@then("The delta table will be populated with the correct data for all updated records in batch file")
274275
def validate_imms_delta_table_for_updated_records(context):
275276
if context.delta_cache is None:
@@ -289,14 +290,63 @@ def validate_imms_delta_table_for_deleted_records(context):
289290
"The imms event table will be populated with the correct data for '{operation}' event for records in batch file"
290291
)
291292
)
292-
def validate_imms_event_table_for_all_records_in_batch_file(context, operation: Operation):
293+
def validate_imms_event_table_for_given_operation_event(context, operation):
294+
validate_imms_event_table_for_all_records_in_batch_file(context, operation)
295+
296+
297+
@then("The imms event table will be populated with the correct data for reinstated record in batch file")
298+
def validate_imms_event_table_for_reinstated_event(context):
299+
validate_imms_event_table_for_all_records_in_batch_file(context, "updated", reinstated=True)
300+
301+
302+
@then("all rejected records are listed in the csv bus ack file and no imms id is generated")
303+
def all_record_are_rejected_for_given_field_name(context):
304+
file_rows = read_and_validate_csv_bus_ack_file_content(context)
305+
all_valid = validate_bus_ack_file_for_error(context, file_rows)
306+
assert all_valid, "One or more records failed validation checks"
307+
308+
309+
@then(parsers.parse("MNS event will be triggered with correct data for all '{event_type}' events where NHS is not null"))
310+
def mns_event_will_be_triggered_with_correct_data_for_created_events_in_batch_file(context, event_type):
311+
if context.mns_validation_required.strip().lower() != "true":
312+
print(
313+
f"MNS event validation is skipped since mns_validation_required is set to {context.mns_validation_required}"
314+
)
315+
return
316+
317+
action = event_type.upper() if event_type.upper() in ["CREATE", "UPDATE"] else "CREATE"
318+
319+
df = context.vaccine_df.dropna(subset=["IMMS_ID"]).copy()
320+
df["IMMS_ID_CLEAN"] = df["IMMS_ID"].astype(str).str.replace("Immunization#", "", regex=False)
321+
322+
valid_rows = list(df.itertuples(index=False))
323+
324+
if not valid_rows:
325+
print("No valid NHS rows found — skipping MNS validation.")
326+
return
327+
328+
mns_event_will_be_triggered_for_batch_record(context=context, action=action, valid_rows=valid_rows)
329+
330+
331+
@then("Api updated event will trigger MNS event with correct data")
332+
def mns_event_will_be_triggered_with_correct_data_for_api_updated_events(context):
333+
mns_event_will_be_triggered_with_correct_data(context=context, action="UPDATE")
334+
335+
336+
def normalize(value):
337+
return "" if pd.isna(value) or value == "" else value
338+
339+
340+
def validate_imms_event_table_for_all_records_in_batch_file(context, operation: Operation, reinstated=False):
293341
mapping = ActionMap[operation.lower()]
294342
df = context.vaccine_df[context.vaccine_df["ACTION_FLAG"].str.lower() == mapping.action_flag.value.lower()]
295343

296344
df["UNIQUE_ID_COMBINED"] = df["UNIQUE_ID_URI"].astype(str) + "#" + df["UNIQUE_ID"].astype(str)
297345
valid_rows = df[df["UNIQUE_ID_COMBINED"].notnull() & (df["UNIQUE_ID_COMBINED"] != "nan#nan")]
298346

299-
for idx, row in valid_rows.iterrows():
347+
unique_rows = valid_rows.drop_duplicates(subset=["UNIQUE_ID_COMBINED"])
348+
349+
for idx, row in unique_rows.iterrows():
300350
unique_id_combined = row["UNIQUE_ID_COMBINED"]
301351
batch_record = {k: normalize(v) for k, v in row.to_dict().items()}
302352

@@ -339,48 +389,28 @@ def validate_imms_event_table_for_all_records_in_batch_file(context, operation:
339389
("Version", int(context.expected_version), int(item.get("Version"))),
340390
]
341391

392+
actualDeletedAt = item.get("DeletedAt")
393+
342394
for name, expected, actual in fields_to_compare:
343395
check.is_true(expected == actual, f"Expected {name}: {expected}, Actual {actual}")
344396

345-
validate_to_compare_batch_record_with_event_table_record(context, batch_record, created_event)
346-
347-
348-
@then("all rejected records are listed in the csv bus ack file and no imms id is generated")
349-
def all_record_are_rejected_for_given_field_name(context):
350-
file_rows = read_and_validate_csv_bus_ack_file_content(context)
351-
all_valid = validate_bus_ack_file_for_error(context, file_rows)
352-
assert all_valid, "One or more records failed validation checks"
353-
354-
355-
@then(parsers.parse("MNS event will be triggered with correct data for all '{event_type}' events where NHS is not null"))
356-
def mns_event_will_be_triggered_with_correct_data_for_created_events_in_batch_file(context, event_type):
357-
if context.mns_validation_required.strip().lower() != "true":
358-
print(
359-
f"MNS event validation is skipped since mns_validation_required is set to {context.mns_validation_required}"
360-
)
361-
return
362-
363-
action = event_type.upper() if event_type.upper() in ["CREATE", "UPDATE"] else "CREATE"
364-
365-
df = context.vaccine_df.dropna(subset=["IMMS_ID"]).copy()
366-
df["IMMS_ID_CLEAN"] = df["IMMS_ID"].astype(str).str.replace("Immunization#", "", regex=False)
367-
368-
valid_rows = list(df.itertuples(index=False))
369-
370-
if not valid_rows:
371-
print("No valid NHS rows found — skipping MNS validation.")
372-
return
373-
374-
mns_event_will_be_triggered_for_batch_record(context=context, action=action, valid_rows=valid_rows)
375-
376-
377-
@then("Api updated event will trigger MNS event with correct data")
378-
def mns_event_will_be_triggered_with_correct_data_for_api_updated_events(context):
379-
mns_event_will_be_triggered_with_correct_data(context=context, action="UPDATE")
380-
397+
if Operation[operation].value == "DELETE":
398+
check.is_true(
399+
actualDeletedAt is not None and actualDeletedAt > 0,
400+
f"Expected DeletedAt to be a Unix timestamp, got {actualDeletedAt}",
401+
)
402+
elif reinstated:
403+
check.is_true(
404+
actualDeletedAt == "reinstated",
405+
f"Expected DeletedAt: None for reinstated record, got {actualDeletedAt}",
406+
)
407+
else:
408+
check.is_true(
409+
actualDeletedAt is None,
410+
f"Expected DeletedAt: None, Actual {actualDeletedAt}",
411+
)
381412

382-
def normalize(value):
383-
return "" if pd.isna(value) or value == "" else value
413+
validate_to_compare_batch_record_with_event_table_record(context, batch_record, created_event)
384414

385415

386416
def create_batch_file(context, file_ext: str = "csv", fileName: str = None, delimiter: str = "|"):
@@ -450,19 +480,19 @@ def preload_delta_data(context):
450480
context.delta_cache[clean_id] = {"rows": group, "delta_items": delta_items}
451481

452482

453-
def validate_imms_delta_table_for_newly_created_records_in_batch_file(context):
483+
def validate_imms_delta_table_for_newly_created_records_in_batch_file(context, expected_number_of_items=1):
454484
for clean_id, data in context.delta_cache.items():
455485
rows = data["rows"]
456486
delta_items = data["delta_items"]
457487

458488
create_items = [i for i in delta_items if i.get("Operation") == "CREATE"]
459489

460490
check.is_true(
461-
len(create_items) == 1,
462-
f"Expected exactly 1 CREATE record for IMMS_ID {clean_id}, found {len(create_items)}",
491+
len(create_items) == expected_number_of_items,
492+
f"Expected exactly {expected_number_of_items} CREATE record(s) for IMMS_ID {clean_id}, found {len(create_items)}",
463493
)
464494

465-
create_item = create_items[0]
495+
create_item = max(create_items, key=lambda x: x.get("SequenceNumber", -1))
466496

467497
for _, row in rows[rows["ACTION_FLAG"] == "NEW"].iterrows():
468498
batch_record = {k: normalize(v) for k, v in row.to_dict().items()}
@@ -497,23 +527,29 @@ def validate_imms_delta_table_for_updated_records_in_batch_file(context):
497527
)
498528

499529

500-
def validate_imms_delta_table_for_deleted_records_in_batch_file(context):
530+
def validate_imms_delta_table_for_deleted_records_in_batch_file(context, expected_number_of_items=1):
501531
for clean_id, data in context.delta_cache.items():
502532
rows = data["rows"]
503533
delta_items = data["delta_items"]
504534

505-
delete_item = next((i for i in delta_items if i.get("Operation") == "DELETE"), None)
535+
delete_items = [i for i in delta_items if i.get("Operation") == "DELETE"]
506536

507-
check.is_true(delete_item, f"No DELETE record for IMMS_ID {clean_id}")
537+
check.is_true(
538+
len(delete_items) == expected_number_of_items,
539+
f"Expected exactly {expected_number_of_items} DELETE record(s) for IMMS_ID {clean_id}, found {len(delete_items)}",
540+
)
541+
542+
delete_item = max(delete_items, key=lambda x: x.get("SequenceNumber", -1))
508543

509544
delete_rows = rows[rows["ACTION_FLAG"] == "DELETE"]
510545

511546
check.is_true(
512-
len(delete_rows) == 1,
513-
f"Expected exactly 1 DELETE row in batch file for IMMS_ID {clean_id}, found {len(delete_rows)}",
547+
len(delete_rows) == expected_number_of_items,
548+
f"Expected exactly {expected_number_of_items} DELETE row(s) in batch file for IMMS_ID {clean_id}, found {len(delete_rows)}",
514549
)
515550

516551
row = delete_rows.iloc[0]
552+
517553
batch_record = {k: normalize(v) for k, v in row.to_dict().items()}
518554

519555
validate_imms_delta_record_with_batch_record(

tests/e2e_automation/features/batchTests/Steps/test_delete_batch_steps.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,20 @@ def validate_imms_event_table_for_delete_event(context):
8282
@then("The delta table will have delete entry with no change to record detail")
8383
def validate_delta_table_for_delete_event(context):
8484
validate_imms_delta_table_by_deleted_ImmsID(context)
85+
86+
87+
@given(
88+
"batch file is created for below data as full dataset and each record delete and the followed with create/update action flag"
89+
)
90+
@ignore_if_local_run
91+
def valid_batch_file_is_created_with_delete_action_flag_and_create_update_action_flag(datatable, context):
92+
build_dataFrame_using_datatable(datatable, context)
93+
df_new = context.vaccine_df.copy()
94+
df_update = df_new.copy()
95+
df_update["ACTION_FLAG"] = "DELETE"
96+
df_reinstated = df_new.copy()
97+
df_reinstated.iloc[0, df_reinstated.columns.get_loc("ACTION_FLAG")] = "NEW"
98+
df_reinstated.iloc[1, df_reinstated.columns.get_loc("ACTION_FLAG")] = "UPDATE"
99+
context.vaccine_df = pd.concat([df_new, df_update, df_reinstated], ignore_index=True)
100+
create_batch_file(context)
101+
context.expected_version = 2

tests/e2e_automation/features/batchTests/delete_batch.feature

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,22 @@ Feature: Create the immunization event for a patient through batch file and upda
5353
And Json bus ack will only contain file metadata and no failure record entry
5454
And The imms event table status will be updated to delete and no change to record detail
5555
And The delta table will have delete entry with no change to record detail
56+
57+
58+
@vaccine_type_RSV @patient_id_Random @supplier_name_RAVS
59+
Scenario: Verify that the imms event can be reinstated after soft delete through create and/or update Action Flag
60+
Given batch file is created for below data as full dataset and each record delete and the followed with create/update action flag
61+
| patient_id | unique_id |
62+
| Random | reinstate_with_create |
63+
| Random | reinstate_with_update |
64+
When batch file is uploaded in s3 bucket
65+
Then file will be moved to destination bucket and inf ack file will be created
66+
And inf ack file has success status for processed batch file
67+
And bus ack files will be created
68+
And CSV bus ack will not have any entry of successfully processed records
69+
And Json bus ack will only contain file metadata and no failure record entry
70+
And Audit table will have correct status, queue name and record count for the processed batch file
71+
And The imms event table will be populated with the correct data for reinstated record in batch file
72+
And The delta table will be populated with the correct data for all created records in batch file
73+
And The delta table will be populated with the correct data for reinstated record
74+
And The delta table will be populated with the correct data for all deleted records in batch file

0 commit comments

Comments
 (0)