Skip to content

Commit 7ac686d

Browse files
Adding scenario 3 and relevant utils/classes/poms
1 parent c8e4c61 commit 7ac686d

File tree

16 files changed

+856
-34
lines changed

16 files changed

+856
-34
lines changed

classes/pi_subject.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from dataclasses import dataclass, field
22
from typing import Optional
33
from datetime import date
4+
from classes.subject import Subject
45

56

67
@dataclass
@@ -69,3 +70,48 @@ def to_string(self) -> str:
6970
f"replaced_by_nhs_number = {self.replaced_nhs_number}",
7071
]
7172
return "PISubject:\n" + "\n".join(fields)
73+
74+
@staticmethod
75+
def from_subject(subject: "Subject") -> "PISubject":
76+
"""
77+
Creates a PISubject object from a Subject object.
78+
79+
Args:
80+
subject (Subject): The Subject object to convert.
81+
82+
Returns:
83+
PISubject: The populated PISubject object.
84+
85+
"""
86+
gender = subject.get_gender()
87+
if gender is not None:
88+
gender_code = gender.redefined_value
89+
else:
90+
gender_code = 0 # If None setting to "Not known gender"
91+
return PISubject(
92+
screening_subject_id=subject.screening_subject_id,
93+
nhs_number=subject.nhs_number,
94+
family_name=subject.surname,
95+
first_given_names=subject.forename,
96+
other_given_names=subject.other_names,
97+
previous_family_name=subject.previous_surname,
98+
name_prefix=subject.title,
99+
birth_date=subject.date_of_birth,
100+
death_date=subject.date_of_death,
101+
gender_code=gender_code,
102+
address_line_1=subject.address_line1,
103+
address_line_2=subject.address_line2,
104+
address_line_3=subject.address_line3,
105+
address_line_4=subject.address_line4,
106+
address_line_5=subject.address_line5,
107+
postcode=subject.postcode,
108+
gnc_code=subject.registration_code,
109+
gp_practice_code=subject.gp_practice_code,
110+
nhais_deduction_reason=subject.nhais_deduction_reason,
111+
nhais_deduction_date=subject.nhais_deduction_date,
112+
exeter_system=subject.datasource,
113+
removed_to=subject.removed_to_datasource,
114+
pi_reference=None,
115+
superseded_by_nhs_number=None,
116+
replaced_nhs_number=None,
117+
)

classes/repositories/subject_repository.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ def process_pi_subject(self, pio_id: int, pi_subject: PISubject) -> Optional[int
103103

104104
return new_contact_id
105105

106-
def update_pi_subject(self, pi_subject: PISubject) -> None:
106+
def update_pi_subject(self, pio_id: int, pi_subject: PISubject) -> None:
107107
"""
108108
Updates an existing screening subject.
109109
@@ -122,9 +122,7 @@ def update_pi_subject(self, pi_subject: PISubject) -> None:
122122
raise ValueError(
123123
"A PI Reference must be specified when updating an existing subject, for example 'SELF REFERRAL' or 'AUTOMATED TEST'"
124124
)
125-
procedure = "PKG_SSPI.p_process_pi_subject"
126-
params = [pi_subject, None, None, None, None]
127-
self.oracle_db.execute_stored_procedure(procedure, params)
125+
self.process_pi_subject(pio_id, pi_subject)
128126

129127
def get_active_gp_practice_in_hub_and_sc(
130128
self, hub_code: str, screening_centre_code: str

classes/repositories/user_repository.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ def get_role_id_for_role(self, role: "UserRoleType") -> int:
9595
df = self.general_query(role)
9696
return int(df["role_id"].iloc[0])
9797

98-
def get_org_code_for_role(self, role: "UserRoleType") -> int:
98+
def get_org_code_for_role(self, role: "UserRoleType") -> str:
9999
"""
100100
Get the ORG CODE for the role.
101101
@@ -108,4 +108,4 @@ def get_org_code_for_role(self, role: "UserRoleType") -> int:
108108
logging.debug(f"Getting ORG CODE for role: {role.user_code}")
109109

110110
df = self.general_query(role)
111-
return int(df["org_code"].iloc[0])
111+
return str(df["org_code"].iloc[0])

classes/subject.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,11 @@
1010
from classes.sdd_reason_for_change_type import SDDReasonForChangeType
1111
from classes.ss_reason_for_change_type import SSReasonForChangeType
1212
from classes.ssdd_reason_for_change_type import SSDDReasonForChangeType
13+
from classes.user import User
1314
from utils.date_time_utils import DateTimeUtils
15+
from utils.oracle.oracle import OracleDB
1416
import pandas as pd
17+
import logging
1518

1619

1720
@dataclass
@@ -1302,3 +1305,27 @@ def from_dataframe_row(row: pd.Series) -> "Subject":
13021305
}
13031306

13041307
return Subject(**field_map)
1308+
1309+
def populate_subject_object_from_nhs_no(self, nhs_no: str) -> "Subject":
1310+
from utils.oracle.subject_selection_query_builder import (
1311+
SubjectSelectionQueryBuilder,
1312+
)
1313+
1314+
nhs_no_criteria = {"nhs number": nhs_no}
1315+
subject = Subject()
1316+
user = User()
1317+
builder = SubjectSelectionQueryBuilder()
1318+
1319+
query, bind_vars = builder.build_subject_selection_query(
1320+
criteria=nhs_no_criteria,
1321+
user=user,
1322+
subject=subject,
1323+
subjects_to_retrieve=1,
1324+
)
1325+
1326+
logging.debug(
1327+
"[SUBJECT ASSERTIONS] Executing base query to populate subject object"
1328+
)
1329+
1330+
subject_df = OracleDB().execute_query(query, bind_vars)
1331+
return self.from_dataframe_row(subject_df.iloc[0])

classes/user.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from typing import Optional
22
from classes.organisation_complex import Organisation
3-
import pandas as pd
3+
from classes.user_role_type import UserRoleType
44

55

66
class User:
@@ -159,3 +159,30 @@ def from_dataframe_row(self, row) -> "User":
159159
pio_id=row["pio_id"],
160160
organisation=organisation,
161161
)
162+
163+
@staticmethod
164+
def from_user_role_type(user_role_type: "UserRoleType") -> "User":
165+
"""
166+
Creates a User object from a UserRoleType object using UserRepository methods.
167+
168+
Args:
169+
user_role_type (UserRoleType): The UserRoleType object.
170+
171+
Returns:
172+
User: The constructed User object.
173+
"""
174+
from classes.repositories.user_repository import UserRepository
175+
176+
user_repo = UserRepository()
177+
pio_id = user_repo.get_pio_id_for_role(user_role_type)
178+
role_id = user_repo.get_role_id_for_role(user_role_type)
179+
org_id = user_repo.get_org_id_for_role(user_role_type)
180+
org_code = user_repo.get_org_code_for_role(user_role_type)
181+
182+
organisation = Organisation(new_id=org_id, new_code=str(org_code))
183+
return User(
184+
user_id=pio_id,
185+
role_id=role_id,
186+
pio_id=pio_id,
187+
organisation=organisation,
188+
)

pages/screening_practitioner_appointments/appointment_detail_page.py

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from playwright.sync_api import Page, expect
22
from pages.base_page import BasePage
3+
from enum import StrEnum
34

45

56
class AppointmentDetailPage(BasePage):
@@ -13,6 +14,10 @@ def __init__(self, page: Page):
1314
self.attended_check_box = self.page.locator("#UI_ATTENDED")
1415
self.calendar_button = self.page.get_by_role("button", name="Calendar")
1516
self.save_button = self.page.get_by_role("button", name="Save")
17+
self.cancel_radio = self.page.get_by_role("radio", name="Cancel")
18+
self.reason_for_cancellation_dropwdown = self.page.get_by_label(
19+
"Reason for Cancellation"
20+
)
1621

1722
def check_attendance_radio(self) -> None:
1823
"""Checks the attendance radio button."""
@@ -26,9 +31,16 @@ def click_calendar_button(self) -> None:
2631
"""Clicks the calendar button."""
2732
self.click(self.calendar_button)
2833

29-
def click_save_button(self) -> None:
30-
"""Clicks the save button."""
31-
self.click(self.save_button)
34+
def click_save_button(self, accept_dialog: bool = False) -> None:
35+
"""
36+
Clicks the save button.
37+
Args:
38+
accept_dialog (bool): Whether to accept the dialog.
39+
"""
40+
if accept_dialog:
41+
self.safe_accept_dialog(self.save_button)
42+
else:
43+
self.click(self.save_button)
3244

3345
def verify_text_visible(self, text: str) -> None:
3446
"""Verifies that the specified text is visible on the page."""
@@ -60,3 +72,29 @@ def wait_for_attendance_radio(self, timeout_duration: float = 30000) -> None:
6072
timeout_duration - elapsed if timeout_duration - elapsed > 0 else 1000
6173
)
6274
)
75+
76+
def check_cancel_radio(self) -> None:
77+
"""Checks the cancel radio button."""
78+
self.cancel_radio.check()
79+
80+
def select_reason_for_cancellation_option(self, option: str) -> None:
81+
"""
82+
Selects the reason for cancellation from the dropdown.
83+
Args:
84+
option: The reason for cancellation to select.
85+
"""
86+
self.reason_for_cancellation_dropwdown.select_option(value=option)
87+
88+
89+
class ReasonForCancellationOptions(StrEnum):
90+
"""Enum for cancellation reason options"""
91+
92+
PATIENT_REQUESTS_DISCHARGE_FROM_SCREENING = "6008"
93+
PATIENT_UNSUITABLE_RECENTLY_SCREENED = "6007"
94+
PATIENT_UNSUITABLE_CURRENTLY_UNDERGOING_TREATMENT = "6006"
95+
PATIENT_CANCELLED_TO_CONSIDER = "6005"
96+
PATIENT_CANCELLED_MOVED_OUT_OF_AREA = "6003"
97+
SCREENING_CENTRE_CANCELLED_OTHER_REASON = "6002"
98+
CLINIC_UNAVAILABLE = "6001"
99+
PRACTITIONER_UNAVAILABLE = "6000"
100+
PATIENT_CANCELLED_OTHER_REASON = "6004"
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from playwright.sync_api import Page
2+
from pages.base_page import BasePage
3+
4+
5+
class ReopenFOBTScreeningEpisodePage(BasePage):
6+
"""Reopen FOBT Screening Episode Page locators, and methods for interacting with the page."""
7+
8+
def __init__(self, page: Page):
9+
super().__init__(page)
10+
self.page = page
11+
12+
self.reopen_to_book_an_assessment_button = self.page.get_by_role(
13+
"button", name="Reopen to book an assessment"
14+
)
15+
16+
def click_reopen_to_book_an_assessment_button(self) -> None:
17+
"""Click the 'Reopen to book an assessment' button."""
18+
self.safe_accept_dialog(self.reopen_to_book_an_assessment_button)

pages/screening_subject_search/subject_screening_summary_page.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ def __init__(self, page: Page):
8383
self.latest_event_status_cell = self.page.locator(
8484
"td.epihdr_label:text('Latest Event Status') + td.epihdr_data"
8585
)
86+
self.reopen_fobt_screening_episode_button = self.page.get_by_role(
87+
"button", name="Reopen FOBT Screening Episode"
88+
)
8689

8790
def wait_for_page_title(self) -> None:
8891
"""Waits for the page to be the Subject Screening Summary"""
@@ -393,6 +396,10 @@ def assert_latest_event_status(self, expected_status: str) -> None:
393396
actual_status == expected_status
394397
), f"[LATEST EVENT STATUS MISMATCH] Expected '{expected_status}', but found '{actual_status}' in UI."
395398

399+
def click_reopen_fobt_screening_episode_button(self) -> None:
400+
"""Click on the 'Reopen FOBT Screening Episode' button"""
401+
self.click(self.reopen_fobt_screening_episode_button)
402+
396403

397404
class ChangeScreeningStatusOptions(Enum):
398405
"""Enum for Change Screening Status options."""

tests/regression/regression_tests/fobt_regression_tests/test_scenario_1.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,12 @@ def test_scenario_1(page: Page) -> None:
5252
"age (y/d)": "65/25",
5353
"active gp practice in hub/sc": "BCS01/BCS001",
5454
}
55-
nhs_no = CreateSubjectSteps().create_custom_subject(requirements, user_role)
55+
nhs_no = CreateSubjectSteps().create_custom_subject(requirements)
5656
if nhs_no is None:
5757
raise ValueError("NHS No is 'None'")
5858

5959
# Then Comment: NHS number
60-
logging.info(f"Created subject's NHS number: {nhs_no}")
60+
logging.info(f"[SUBJECT CREATION] Created subject's NHS number: {nhs_no}")
6161

6262
# Then my subject has been updated as follows:
6363
criteria = {

tests/regression/regression_tests/fobt_regression_tests/test_scenario_2.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ def test_scenario_2(page: Page) -> None:
5656
"age (y/d)": "66/130",
5757
"active gp practice in hub/sc": "BCS01/BCS001",
5858
}
59-
nhs_no = CreateSubjectSteps().create_custom_subject(requirements, user_role)
59+
nhs_no = CreateSubjectSteps().create_custom_subject(requirements)
6060
if nhs_no is None:
6161
pytest.fail("Failed to create subject: NHS number not returned.")
6262

0 commit comments

Comments
 (0)