Skip to content

Commit e082c48

Browse files
authored
Ved 982 updated dpsfull batch scenario (#1371)
* added DPSFULL batch scenario * updated fix
1 parent 9e0b52f commit e082c48

10 files changed

Lines changed: 131 additions & 38 deletions

File tree

tests/e2e_automation/features/APITests/search.feature

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,6 @@ Feature: Search the immunization of a patient
235235
When I send a search request with Post method using identifier parameter for Immunization event created
236236
Then The request will be successful with the status code '200'
237237
And correct immunization event is returned in the response
238-
And MNS event will not be triggered for the update event
239238

240239
@Delete_cleanUp @vaccine_type_FLU @patient_id_Random @supplier_name_Postman_Auth
241240
Scenario: Flu event is created and search post request fetch the only one record matched with identifier and _elements

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

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import copy
12
import json
23
import random
34
import uuid
@@ -329,7 +330,8 @@ def validate_etag_in_header(context):
329330
@when("I subsequently update the vaccination details of the original immunization event")
330331
def send_update_for_vaccination_detail(context):
331332
get_update_url_header(context, str(context.expected_version))
332-
context.update_object = convert_to_update(context.immunization_object, context.ImmsID)
333+
context.update_object = copy.deepcopy(context.immunization_object)
334+
context.update_object = convert_to_update(context.update_object, context.ImmsID)
333335
context.update_object.extension = [build_vaccine_procedure_extension(context.vaccine_type.upper())]
334336
vaccine_details = get_vaccine_details(context.vaccine_type.upper())
335337
context.update_object.vaccineCode = vaccine_details["vaccine_code"]
@@ -341,7 +343,8 @@ def send_update_for_vaccination_detail(context):
341343
@when("I update the address of the original immunization event")
342344
def send_update_for_immunization_event(context):
343345
get_update_url_header(context, str(context.expected_version))
344-
context.update_object = convert_to_update(context.immunization_object, context.ImmsID)
346+
context.update_object = copy.deepcopy(context.immunization_object)
347+
context.update_object = convert_to_update(context.update_object, context.ImmsID)
345348
context.update_object.contained[1].address[0].city = "Updated City"
346349
context.update_object.contained[1].address[0].state = "Updated State"
347350
trigger_the_updated_request(context)
@@ -395,14 +398,7 @@ def mns_event_will_not_be_triggered_for_the_event(context):
395398

396399
@then("MNS event will not be triggered for the update event")
397400
def validate_mns_event_not_triggered_for_updated_event(context):
398-
message_body = read_message(
399-
context,
400-
queue_type="notification",
401-
wait_time_seconds=5,
402-
max_total_wait_seconds=20,
403-
)
404-
print("no MNS update event is created")
405-
assert message_body is None, "Not expected a message but queue returned a message"
401+
mns_event_will_not_be_triggered_for_the_event(context)
406402

407403

408404
def trigger_the_updated_request(context):
@@ -482,10 +478,11 @@ def validate_sqs_message(context, message_body, action):
482478
f"msn event for {action} Filtering is missing in the message body",
483479
)
484480

485-
check.is_true(
486-
normalize(message_body.filtering.generalpractitioner) == normalize(context.gp_code),
487-
f"msn event for {action} GP code mismatch: expected {context.gp_code}, got {message_body.filtering.generalpractitioner}",
488-
)
481+
if context.gp_code:
482+
check.is_true(
483+
normalize(message_body.filtering.generalpractitioner) == normalize(context.gp_code),
484+
f"msn event for {action} GP code mismatch: expected {context.gp_code}, got {message_body.filtering.generalpractitioner}",
485+
)
489486

490487
expected_org = context.immunization_object.performer[1].actor.identifier.value
491488
check.is_true(
@@ -498,10 +495,11 @@ def validate_sqs_message(context, message_body, action):
498495
f"msn event for {action} Source application mismatch: expected {context.supplier_name}, got {message_body.filtering.sourceapplication}",
499496
)
500497

501-
check.is_true(
502-
message_body.filtering.subjectage == context.patient_age,
503-
f"msn event for {action} Age mismatch: expected {context.patient_age}, got {message_body.filtering.subjectage}",
504-
)
498+
if context.patient_age:
499+
check.is_true(
500+
message_body.filtering.subjectage == context.patient_age,
501+
f"msn event for {action} Age mismatch: expected {context.patient_age}, got {message_body.filtering.subjectage}",
502+
)
505503

506504
check.is_true(
507505
message_body.filtering.immunisationtype == context.vaccine_type.upper(),
@@ -544,7 +542,12 @@ def mns_event_will_be_triggered_with_correct_data(context, action):
544542
print(f"Read {action}d message from SQS: {message_body}")
545543
assert message_body is not None, f"Expected a {action} message but queue returned empty"
546544
context.gp_code = get_gp_code_by_nhs_number(context.patient.identifier[0].value)
547-
context.patient_age = calculate_age(context.patient.birthDate, context.immunization_object.occurrenceDateTime)
545+
patient_DOB = (
546+
context.immunization_object.contained[1].birthDate
547+
if action.upper() == "CREATE"
548+
else context.update_object.contained[1].birthDate
549+
)
550+
context.patient_age = calculate_age(patient_DOB, context.immunization_object.occurrenceDateTime)
548551
validate_sqs_message(context, message_body, action)
549552
else:
550553
print(

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

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import copy
12
import uuid
23

34
from pytest_bdd import parsers, scenarios, then, when
@@ -58,15 +59,17 @@ def validate_delta_table_for_updated_event(context):
5859
)
5960
def send_update_for_immunization_event_with_occurrenceDateTime(context, DateText):
6061
get_update_url_header(context, str(context.expected_version))
61-
context.update_object = convert_to_update(context.immunization_object, context.ImmsID)
62+
context.update_object = copy.deepcopy(context.immunization_object)
63+
context.update_object = convert_to_update(context.update_object, context.ImmsID)
6264
context.update_object.occurrenceDateTime = generate_date(DateText)
6365
trigger_the_updated_request(context)
6466

6567

6668
@when(parsers.parse("Send a update for Immunization event created with recorded being updated to '{DateText}'"))
6769
def send_update_for_immunization_event_with_recorded_date_update(context, DateText):
6870
get_update_url_header(context, str(context.expected_version))
69-
context.update_object = convert_to_update(context.immunization_object, context.ImmsID)
71+
context.update_object = copy.deepcopy(context.immunization_object)
72+
context.update_object = convert_to_update(context.update_object, context.ImmsID)
7073
context.update_object.recorded = generate_date(DateText)
7174
trigger_the_updated_request(context)
7275

@@ -76,15 +79,17 @@ def send_update_for_immunization_event_with_recorded_date_update(context, DateTe
7679
)
7780
def send_update_for_immunization_event_with_dob_update(context, DateText):
7881
get_update_url_header(context, str(context.expected_version))
79-
context.update_object = convert_to_update(context.immunization_object, context.ImmsID)
82+
context.update_object = copy.deepcopy(context.immunization_object)
83+
context.update_object = convert_to_update(context.update_object, context.ImmsID)
8084
context.update_object.contained[1].birthDate = generate_date(DateText)
8185
trigger_the_updated_request(context)
8286

8387

8488
@when(parsers.parse("Send a update for Immunization event created with expiration date being updated to '{DateText}'"))
8589
def send_update_for_immunization_event_with_expiration_date_update(context, DateText):
8690
get_update_url_header(context, str(context.expected_version))
87-
context.update_object = convert_to_update(context.immunization_object, context.ImmsID)
91+
context.update_object = copy.deepcopy(context.immunization_object)
92+
context.update_object = convert_to_update(context.update_object, context.ImmsID)
8893
context.update_object.expirationDate = generate_date(DateText)
8994
trigger_the_updated_request(context)
9095

@@ -94,7 +99,8 @@ def send_update_request_for_invalid_immunization_id(context):
9499
valid_json_payload_is_created(context)
95100
context.ImmsID = str(uuid.uuid4())
96101
get_update_url_header(context, str(context.expected_version))
97-
context.update_object = convert_to_update(context.immunization_object, context.ImmsID)
102+
context.update_object = copy.deepcopy(context.immunization_object)
103+
context.update_object = convert_to_update(context.update_object, context.ImmsID)
98104
trigger_the_updated_request(context)
99105

100106

@@ -104,7 +110,8 @@ def send_update_request_for_invalid_etag(context, Etag):
104110
context.ImmsID = str(uuid.uuid4())
105111
context.version = Etag
106112
get_update_url_header(context, Etag)
107-
context.update_object = convert_to_update(context.immunization_object, context.ImmsID)
113+
context.update_object = copy.deepcopy(context.immunization_object)
114+
context.update_object = convert_to_update(context.update_object, context.ImmsID)
108115
trigger_the_updated_request(context)
109116

110117

tests/e2e_automation/features/APITests/update.feature

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ Feature: Update the immunization of a patient
2222
And The Response JSONs should contain correct error message for 'forbidden' access
2323

2424

25-
@delete_cleanup @vaccine_type_RSV @patient_id_NullNHS @supplier_name_RAVS
25+
@delete_cleanup @vaccine_type_RSV @patient_id_Random @supplier_name_RAVS
2626
Scenario: verify that vaccination record can be updated with valid vaccination detail
2727
Given I have created a valid vaccination record
2828
When I update the address of the original immunization event
@@ -31,7 +31,7 @@ Feature: Update the immunization of a patient
3131
And The X-Request-ID and X-Correlation-ID keys in header will populate correctly
3232
And The imms event table will be populated with the correct data for 'updated' event
3333
And The delta table will be populated with the correct data for updated event
34-
And MNS event will not be triggered for the update event
34+
And MNS event will be triggered with correct data for Updated event
3535

3636

3737
@smoke
@@ -80,6 +80,7 @@ Feature: Update the immunization of a patient
8080
When Send a update for Immunization event created with occurrenceDateTime being updated to '<Date>'
8181
Then The request will be unsuccessful with the status code '400'
8282
And The Response JSONs should contain correct error message for 'invalid_OccurrenceDateTime'
83+
And MNS event will not be triggered for the update event
8384
Examples:
8485
| Date |
8586
| future_occurrence |

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

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,21 @@ def valid_batch_file_is_created_with_details(datatable, context):
100100
create_batch_file(context)
101101

102102

103+
@given("batch file is received for below data form DPS with all three action flag for each record")
104+
@ignore_if_local_run
105+
def valid_batch_file_is_created_for_DPSFULL(datatable, context):
106+
build_dataFrame_using_datatable(datatable, context)
107+
df_new = context.vaccine_df.copy()
108+
df_update = df_new.copy()
109+
df_update[["ACTION_FLAG", "EXPIRY_DATE"]] = ["UPDATE", "20281231"]
110+
df_delete = df_new.copy()
111+
df_delete[["ACTION_FLAG", "EXPIRY_DATE"]] = ["DELETE", "20281231"]
112+
context.vaccine_df = pd.concat([df_new, df_update, df_delete], ignore_index=True)
113+
file_name = f"{context.vaccine_type}_Vaccinations_v5_DPSFULL"
114+
create_batch_file(context, fileName=file_name)
115+
context.expected_version = 2
116+
117+
103118
@given("batch file is created for below data as full dataset with file extension dat")
104119
@ignore_if_local_run
105120
def valid_batch_file_is_created_with_details_and_dat_extension(datatable, context):
@@ -227,6 +242,34 @@ def validate_imms_delta_table_for_created_records_in_batch_file(context):
227242
validate_imms_delta_table_for_newly_created_records_in_batch_file(context)
228243

229244

245+
@then("The delta table will not be populated with DPSFULL records in batch file")
246+
def validate_imms_delta_table_for_dpsfull_records(context):
247+
df = context.vaccine_df
248+
249+
check.is_true("IMMS_ID" in df.columns, "Column 'IMMS_ID' not found in vaccine_df")
250+
251+
valid_rows = df[df["IMMS_ID"].notnull()]
252+
check.is_true(not valid_rows.empty, "No rows with non-null IMMS_ID found in vaccine_df")
253+
254+
grouped = valid_rows.groupby("IMMS_ID")
255+
256+
for imms_id in grouped:
257+
clean_id = imms_id[0].replace("Immunization#", "")
258+
259+
delta_items = fetch_immunization_int_delta_detail_by_immsID(
260+
context.aws_profile_name,
261+
clean_id,
262+
context.S3_env,
263+
max_attempts=2,
264+
delay=5,
265+
)
266+
267+
check.is_true(
268+
not delta_items,
269+
f"Delta records were unexpectedly found for IMMS_ID: {clean_id}",
270+
)
271+
272+
230273
@then("The delta table will be populated with the correct data for all updated records in batch file")
231274
def validate_imms_delta_table_for_updated_records(context):
232275
if context.delta_cache is None:
@@ -483,16 +526,18 @@ def validate_imms_delta_table_for_deleted_records_in_batch_file(context):
483526

484527

485528
def _is_null_nhs_row(row) -> bool:
486-
return str(row.UNIQUE_ID).startswith("NullNHS") or str(row.NHS_NUMBER).strip() in ("", "None", "nan")
529+
return str(row.UNIQUE_ID).startswith("NullNHS") or str(row.NHS_NUMBER).strip() in (
530+
"",
531+
"None",
532+
"nan",
533+
)
487534

488535

489536
def _assert_no_mns_events_for_null_nhs_rows(context, null_nhs_rows, wait_seconds=20):
490537
if not null_nhs_rows:
491538
print("No NullNHS rows — skipping negative MNS check.")
492539
return
493540

494-
# Use an unreachable expected_count so the poller runs for the full wait_seconds,
495-
# then check that nothing arrived for these datarefs.
496541
unexpected = read_messages_for_batch(
497542
context,
498543
queue_type="notification",

tests/e2e_automation/features/batchTests/create_batch.feature

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,3 +300,25 @@ Feature: Create the immunization event for a patient through batch file
300300
And The imms event table will be populated with the correct data for 'created' event for records in batch file
301301
And The delta table will be populated with the correct data for all created records in batch file
302302
And MNS event will be triggered with correct data for all 'CREATE' events where NHS is not null
303+
304+
305+
@vaccine_type_HPV @supplier_name_DPSFULL
306+
Scenario: Verify that vaccination record will be created through batch file received from DPS
307+
Given batch file is received for below data form DPS with all three action flag for each record
308+
| patient_id | unique_id |
309+
| Random | Valid_NhsNumber |
310+
| InvalidInPDS | InvalidInPDS_NhsNumber |
311+
| SFlag | SFlag_NhsNumber |
312+
| Mod11_NHS | Mod11_NhSNumber |
313+
| NullNHS | NullNHS_NhsNumber |
314+
| OldNHSNo | OldNHS_NhsNumber |
315+
| NO_GP_NHS | NO_GP_NhsNumber |
316+
When batch file is uploaded in s3 bucket
317+
Then file will be moved to destination bucket and inf ack file will be created
318+
And inf ack file has success status for processed batch file
319+
And bus ack files will be created
320+
And CSV bus ack will not have any entry of successfully processed records
321+
And Json bus ack will only contain file metadata and no failure record entry
322+
And Audit table will have correct status, queue name and record count for the processed batch file
323+
And The imms event table will be populated with the correct data for 'deleted' event for records in batch file
324+
And The delta table will not be populated with DPSFULL records in batch file

tests/e2e_automation/features/conftest.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,8 @@ def context(request, global_context, temp_apigee_apps: list[ApigeeApp] | None) -
135135
ctx.patient_id = tag.split("patient_id_")[1]
136136
if tag.startswith("supplier_name_"):
137137
ctx.supplier_name = tag.split("supplier_name_")[1]
138-
get_tokens(ctx, ctx.supplier_name)
138+
if ctx.supplier_name != "DPSFULL":
139+
get_tokens(ctx, ctx.supplier_name)
139140
ctx.supplier_name = tag.split("supplier_name_")[1]
140141
ctx.supplier_ods_code = SupplierNameWithODSCode[ctx.supplier_name].value
141142

@@ -163,7 +164,8 @@ def pytest_bdd_after_scenario(request, feature, scenario):
163164

164165
if "delete_cleanup_batch" in tags:
165166
if "IMMS_ID" in context.vaccine_df.columns and context.vaccine_df["IMMS_ID"].notna().any():
166-
get_tokens(context, context.supplier_name)
167+
supplier_name = context.supplier_name if context.supplier_name != "DPSFULL" else "Postman_Auth"
168+
get_tokens(context, supplier_name)
167169

168170
df = context.vaccine_df.dropna(subset=["IMMS_ID"]).copy()
169171
df["IMMS_ID_CLEAN"] = df["IMMS_ID"].astype(str).str.replace("Immunization#", "", regex=False)

tests/e2e_automation/pytest.ini

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,17 @@ markers =
1919
Delete_Batch_Feature: tag for delete batch feature tests
2020
Delete_cleanUp: tag for scenarios that require cleanup after execution
2121
delete_cleanup_batch: tag for batch scenarios that require cleanup after execution
22+
smoke: test tag for smoke suite
23+
functional: test tag for regression suite
2224
patient_id_OldNHS: tag for old NHS patient ID scenarios
2325
patient_id_ValidNHS: tag for valid NHS patient ID scenarios
2426
patient_id_SFlag: tag for patient id SFlag scenario
2527
patient_id_SupersedeNhsNo: tag for patient id Supersede NHS Number scenario
28+
patient_id_NullNHS: tag for null NHS patient ID scenarios
29+
patient_id_InvalidInPDS: tag for invalid NHS patient ID scenarios
30+
patient_id_InvalidMOD11Check: tag for invalid MOD11 check NHS patient ID scenarios
31+
patient_id_Mod11_NHS: tag for Mod11 NHS patient ID scenarios
32+
patient_id_NO_GP_NHS: tag for NHS patient ID with no GP scenarios
2633
vaccine_type_RSV: tag for RSV vaccine type scenarios
2734
vaccine_type_PNEUMOCOCCAL: tag for PNEUMOCOCCAL vaccine type scenarios
2835
vaccine_type_FLU: tag for FLU vaccine type scenarios
@@ -52,4 +59,6 @@ markers =
5259
supplier_name_PINNACLE: tag for Pinnacle supplier name scenarios
5360
supplier_name_TPP: tag for TPP supplier name scenarios
5461
supplier_name_MEDICUS: tag for MEDICUS supplier name scenarios
55-
supplier_name_CEGEDIM: tag for CEGEDIM supplier name scenarios
62+
supplier_name_CEGEDIM: tag for CEGEDIM supplier name scenarios
63+
supplier_name_DPSFULL: tag for DPSFULL supplier name scenarios
64+

tests/e2e_automation/src/dynamoDB/dynamo_db_helper.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,13 +89,17 @@ def fetch_immunization_events_detail_by_IdentifierPK(
8989
return response
9090

9191

92-
def fetch_immunization_int_delta_detail_by_immsID(aws_profile_name: str, ImmsID: str, env: str, expected_item: int = 1):
92+
def fetch_immunization_int_delta_detail_by_immsID(
93+
aws_profile_name: str,
94+
ImmsID: str,
95+
env: str,
96+
expected_item: int = 1,
97+
max_attempts=5,
98+
delay=2,
99+
):
93100
db = DynamoDBHelper(aws_profile_name, env)
94101
tableImmsDelta = db.get_delta_table()
95102

96-
max_attempts = 5
97-
delay = 2 # seconds
98-
99103
for attempt in range(1, max_attempts + 1):
100104
response = tableImmsDelta.query(
101105
IndexName="ImmunisationIdIndex",

tests/e2e_automation/utilities/enums.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ class SupplierNameWithODSCode(Enum):
2323
MEDICUS = "YGMYW"
2424
CEGEDIM = "YGM04"
2525
Postman_Auth = "Postman_Auth"
26+
DPSFULL = "DPSFULL"
2627

2728

2829
class GenderCode(Enum):

0 commit comments

Comments
 (0)