Skip to content

Commit 5626da5

Browse files
Feature/bcss 20062 compartment 3 (#12)
<!-- markdownlint-disable-next-line first-line-heading --> ## Description <!-- Describe your changes in detail. --> ## Context Adding compartment 3 and any relevant utils (fit_kit_logged.py and oracle_specific_function.py) Altered bcss_smokescreen_tests.properties to ass values for compartment 3 Altered existing tests to fix issues with broken imports. Some import statements did not contain the folder of the POMs. E.g. in test_fit_test_kits_page.py `from pages.fit_test_kits.log_devices_page import LogDevices` was originally set to from `pages.log_devices_page import LogDevices` <!-- Why is this change required? What problem does it solve? --> ## Type of changes Adding a new compartment for the smokescreen tests and fixing import statements in existing tests. <!-- What types of changes does your code introduce? Put an `x` in all the boxes that apply. --> - [x] Refactoring (non-breaking change) - [x] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would change existing functionality) - [ ] Bug fix (non-breaking change which fixes an issue) ## Checklist <!-- Go over all the following points, and put an `x` in all the boxes that apply. --> - [x] I am familiar with the [contributing guidelines](https://github.com/nhs-england-tools/playwright-python-blueprint/blob/main/CONTRIBUTING.md) - [x] I have followed the code style of the project - [x] I have added tests to cover my changes (where appropriate) - [x] I have updated the documentation accordingly - [ ] This PR is a result of pair or mob programming --- ## Sensitive Information Declaration To ensure the utmost confidentiality and protect your and others privacy, we kindly ask you to NOT including [PII (Personal Identifiable Information) / PID (Personal Identifiable Data)](https://digital.nhs.uk/data-and-information/keeping-data-safe-and-benefitting-the-public) or any other sensitive data in this PR (Pull Request) and the codebase changes. We will remove any PR that do contain any sensitive information. We really appreciate your cooperation in this matter. - [x] I confirm that neither PII/PID nor sensitive data are included in this PR and the codebase changes. --------- Signed-off-by: adrianoaru-nhs <[email protected]> Co-authored-by: Dave Harding <[email protected]>
1 parent b6c7c99 commit 5626da5

File tree

7 files changed

+368
-21
lines changed

7 files changed

+368
-21
lines changed

tests/smokescreen/bcss_smokescreen_tests.properties

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@
1414
# ----------------------------------
1515
# compartment 3
1616
# ----------------------------------
17-
# c3_fit_kit_results_test_org_id=23159
18-
# c3_fit_kit_normal_result=75
19-
# c3_fit_kit_abnormal_result=150
17+
c3_fit_kit_results_test_org_id=23159
18+
c3_fit_kit_normal_result=75
19+
c3_fit_kit_abnormal_result=150
2020
# c3_fit_kit_authorised_user=AUTO1
2121
# c3_fit_kit_analyser_code=HMJackalt1
2222

@@ -66,8 +66,8 @@
6666
# c3_eng_number_of_abnormal_gfobt_kits_to_log=0
6767
# c3_eng_number_of_normal_gfobt_kits_to_log=0
6868
# c3_eng_number_of_weak_positive_gfobt_kits_to_log=0
69-
# c3_eng_number_of_abnormal_fit_kits=7
70-
# c3_eng_number_of_normal_fit_kits=1
69+
c3_eng_number_of_abnormal_fit_kits=9
70+
c3_eng_number_of_normal_fit_kits=1
7171

7272
# ----------------------------------
7373
# compartment 4
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
import logging
2+
import pytest
3+
from playwright.sync_api import Page
4+
from pages.logout.log_out_page import Logout
5+
from utils.batch_processing import batch_processing
6+
from utils.fit_kit_logged import process_kit_data
7+
from utils.screening_subject_page_searcher import verify_subject_event_status_by_nhs_no
8+
from utils.oracle.oracle_specific_functions import (
9+
update_kit_service_management_entity,
10+
execute_fit_kit_stored_procedures,
11+
)
12+
from utils.user_tools import UserTools
13+
from jproperties import Properties
14+
from sys import platform
15+
16+
17+
@pytest.fixture
18+
def smokescreen_properties() -> dict:
19+
"""
20+
Reads the 'bcss_smokescreen_tests.properties' file and populates a 'Properties' object.
21+
Returns a dictionary of properties for use in tests.
22+
23+
Returns:
24+
dict: A dictionary containing the values loaded from the 'bcss_smokescreen_tests.properties' file.
25+
"""
26+
configs = Properties()
27+
if platform == "win32": # File path from content root is required on Windows OS
28+
with open(
29+
"tests/smokescreen/bcss_smokescreen_tests.properties", "rb"
30+
) as read_prop:
31+
configs.load(read_prop)
32+
elif platform == "darwin": # Only the filename is required on macOS
33+
with open("bcss_smokescreen_tests.properties", "rb") as read_prop:
34+
configs.load(read_prop)
35+
return configs.properties
36+
37+
38+
@pytest.mark.smokescreen
39+
@pytest.mark.compartment3
40+
def test_compartment_3(page: Page, smokescreen_properties: dict) -> None:
41+
"""
42+
This is the main compartment 3 method
43+
First it finds any relevant test data from the DB and stores it in a pandas dataframe
44+
Then it separates it out into normal and abnormal results
45+
Once that is done it updates a table on the DB and runs two stored procedures so that these subjects will not have normal/abnormal results on BCSS
46+
It then checks that the status of the subject is as expected using the subject screening summary page
47+
Then it process two batches performing checks on the subjects to ensure they always have the correct event status
48+
"""
49+
UserTools.user_login(page, "Hub Manager State Registered")
50+
51+
# Find data , separate it into normal and abnormal, Add results to the test records in the KIT_QUEUE table (i.e. mimic receiving results from the middleware)
52+
# and get device IDs and their flags
53+
device_ids = process_kit_data(smokescreen_properties)
54+
# Retrieve NHS numbers for each device_id and determine normal/abnormal status
55+
nhs_numbers = []
56+
normal_flags = []
57+
58+
for device_id, is_normal in device_ids:
59+
nhs_number = update_kit_service_management_entity(
60+
device_id, is_normal, smokescreen_properties
61+
)
62+
nhs_numbers.append(nhs_number)
63+
normal_flags.append(
64+
is_normal
65+
) # Store the flag (True for normal, False for abnormal)
66+
67+
# Run two stored procedures to process any kit queue records at status BCSS_READY
68+
try:
69+
execute_fit_kit_stored_procedures()
70+
logging.info("Stored procedures executed successfully.")
71+
except Exception as e:
72+
logging.error(f"Error executing stored procedures: {str(e)}")
73+
raise
74+
75+
# Check the results of the processed FIT kits have correctly updated the status of the associated subjects
76+
# Verify subject event status based on normal or abnormal classification
77+
for nhs_number, is_normal in zip(nhs_numbers, normal_flags):
78+
expected_status = (
79+
"S2 - Normal" if is_normal else "A8 - Abnormal"
80+
) # S2 for normal, A8 for abnormal
81+
logging.info(
82+
f"Verifying NHS number: {nhs_number} with expected status: {expected_status}"
83+
)
84+
85+
try:
86+
verify_subject_event_status_by_nhs_no(page, nhs_number, expected_status)
87+
logging.info(
88+
f"Successfully verified NHS number {nhs_number} with status {expected_status}"
89+
)
90+
except Exception as e:
91+
logging.error(
92+
f"Verification failed for NHS number {nhs_number} with status {expected_status}: {str(e)}"
93+
)
94+
raise
95+
96+
# Process S2 batch
97+
batch_processing(
98+
page,
99+
"S2",
100+
"Subject Result (Normal)",
101+
"S158 - Subject Discharge Sent (Normal)",
102+
True,
103+
)
104+
105+
# Process S158 batch
106+
batch_processing(
107+
page,
108+
"S158",
109+
"GP Result (Normal)",
110+
"S159 - GP Discharge Sent (Normal)",
111+
)
112+
113+
# Log out
114+
Logout(page).log_out()

tests/test_fit_test_kits_page.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,17 @@
33
from pages.base_page import BasePage
44
from pages.fit_test_kits.fit_test_kits_page import FITTestKits
55
from pages.fit_test_kits.fit_rollout_summary_page import FITRolloutSummary
6-
from pages.log_devices_page import LogDevices
6+
from pages.fit_test_kits.log_devices_page import LogDevices
77
from pages.fit_test_kits.view_fit_kit_result_page import ViewFITKitResult
88
from pages.fit_test_kits.kit_service_management_page import KitServiceManagement
99
from pages.fit_test_kits.kit_result_audit_page import KitResultAudit
10-
from pages.view_algorithms_page import ViewAlgorithms
11-
from pages.view_screening_centre_fit_configuration_page import (
10+
from pages.fit_test_kits.view_algorithms_page import ViewAlgorithms
11+
from pages.fit_test_kits.view_screening_centre_fit_configuration_page import (
1212
ViewScreeningCentreFITConfiguration,
1313
)
14-
from pages.screening_incidents_list_page import ScreeningIncidentsList
15-
from pages.manage_qc_products_page import ManageQCProducts
16-
from pages.maintain_analysers_page import MaintainAnalysers
14+
from pages.fit_test_kits.screening_incidents_list_page import ScreeningIncidentsList
15+
from pages.fit_test_kits.manage_qc_products_page import ManageQCProducts
16+
from pages.fit_test_kits.maintain_analysers_page import MaintainAnalysers
1717
from utils.user_tools import UserTools
1818

1919

utils/fit_kit_logged.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
from oracle.oracle import OracleDB
2+
from oracle.oracle_specific_functions import get_kit_id_logged_from_db
3+
import pandas as pd
4+
import logging
5+
import pytest
6+
7+
8+
def process_kit_data(smokescreen_properties: dict) -> list:
9+
"""
10+
This method retrieved the test data needed for compartment 3 and then splits it into two data frames:
11+
- 1 normal
12+
- 1 abnormal
13+
Once the dataframe is split in two it then creates two lists, one for normal and one for abnormal
14+
Each list will either have true or false appended depending on if it is normal or abnormal
15+
"""
16+
# Get test data for compartment 3
17+
kit_id_df = get_kit_id_logged_from_db(smokescreen_properties)
18+
19+
# Split dataframe into two different dataframes, normal and abnormal
20+
normal_fit_kit_df, abnormal_fit_kit_df = split_fit_kits(
21+
kit_id_df, smokescreen_properties
22+
)
23+
24+
# Prepare a list to store device IDs and their respective flags
25+
device_ids = []
26+
27+
# Process normal kits (only 1)
28+
if not normal_fit_kit_df.empty:
29+
device_id = normal_fit_kit_df["device_id"].iloc[0]
30+
logging.info(
31+
f"Processing normal kit with Device ID: {device_id}"
32+
) # Logging normal device_id
33+
device_ids.append((device_id, True)) # Add to the list with normal flag
34+
else:
35+
pytest.fail("No normal kits found for processing.")
36+
37+
# Process abnormal kits (multiple, loop through)
38+
if not abnormal_fit_kit_df.empty:
39+
for index, row in abnormal_fit_kit_df.iterrows():
40+
device_id = row["device_id"]
41+
logging.info(
42+
f"Processing abnormal kit with Device ID: {device_id}"
43+
) # Logging abnormal device_id
44+
device_ids.append((device_id, False)) # Add to the list with abnormal flag
45+
else:
46+
pytest.fail("No abnormal kits found for processing.")
47+
48+
return device_ids
49+
50+
51+
def split_fit_kits(kit_id_df: pd.DataFrame, smokescreen_properties: dict) -> pd.DataFrame:
52+
"""
53+
This method splits the dataframe into two, 1 normal and 1 abnormal
54+
"""
55+
number_of_normal = int(smokescreen_properties["c3_eng_number_of_normal_fit_kits"])
56+
number_of_abnormal = int(
57+
smokescreen_properties["c3_eng_number_of_abnormal_fit_kits"]
58+
)
59+
60+
# Split dataframe into two dataframes
61+
normal_fit_kit_df = kit_id_df.iloc[:number_of_normal]
62+
abnormal_fit_kit_df = kit_id_df.iloc[
63+
number_of_normal : number_of_normal + number_of_abnormal
64+
]
65+
return normal_fit_kit_df, abnormal_fit_kit_df

utils/oracle/oracle.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ def delete_all_users_from_approved_users_table(
126126
self.disconnect_from_db(conn)
127127

128128
def execute_query(
129-
self, query: str
129+
self, query: str, parameters: list | None = None
130130
) -> pd.DataFrame: # To use when "select xxxx" (stored procedures)
131131
"""
132132
This is used to execute any sql queries.
@@ -135,9 +135,7 @@ def execute_query(
135135
conn = self.connect_to_db()
136136
engine = create_engine("oracle+oracledb://", creator=lambda: conn)
137137
try:
138-
logging.info("Attempting to execute query")
139-
df = pd.read_sql(query, engine)
140-
logging.info("Query execution successful!")
138+
df = pd.read_sql(query, engine) if parameters == None else pd.read_sql(query, engine, params = parameters)
141139
except Exception as executionError:
142140
logging.error(
143141
f"Failed to execute query with execution error {executionError}"

0 commit comments

Comments
 (0)