Skip to content

Commit 268a405

Browse files
Added test for MAV-7075
1 parent 5769294 commit 268a405

2 files changed

Lines changed: 225 additions & 2 deletions

File tree

mavis/test/pages/reports/reports_consent_page.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import re
2+
13
from playwright.sync_api import Page
24

35
from mavis.test.annotations import step
@@ -18,3 +20,17 @@ def __init__(self, page: Page) -> None:
1820
def navigate(self) -> None:
1921
self.page.goto("/reports")
2022
self.tabs.click_consent_tab()
23+
24+
def get_children_count(self, category: str) -> int:
25+
category_card = self.page.locator(
26+
f"//div[@class='nhsuk-card__content'][.//h3[normalize-space()='{category}']]"
27+
)
28+
caption_text = category_card.locator(".nhsuk-card__caption").inner_text()
29+
30+
match = re.search(r"(\d+)", caption_text)
31+
if match:
32+
num_children = int(match.group(1))
33+
else:
34+
msg = "Number of children not found"
35+
raise AssertionError(msg)
36+
return num_children

tests/test_reporting_regression.py

Lines changed: 209 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import httpx
66
import pytest
7+
from playwright.sync_api import TimeoutError as PlaywrightTimeoutError
78

89
from mavis.test.constants import Programme
910
from mavis.test.data import ClassFileMapping, VaccsFileMapping
@@ -34,13 +35,23 @@
3435
_yg1, _yg2, _yg3 = random.sample(list(range(7, 12)), 3)
3536
_year_groups = {p.group: _yg1 for p in Programme}
3637

38+
# Separate year groups for consent breakdown test
39+
# (different teams use different year groups to avoid school conflicts)
40+
_available_ygs = [y for y in range(7, 12) if y not in [_yg1, _yg2, _yg3]]
41+
_yg_consent_a, _yg_consent_b = random.sample(_available_ygs, 2)
42+
_year_groups_consent_a = {p.group: _yg_consent_a for p in Programme}
43+
_year_groups_consent_b = {p.group: _yg_consent_b for p in Programme}
44+
3745
_setup_complete = False
46+
_consent_breakdown_setup_complete = False
3847

3948

40-
def _onboard_team(base_url):
49+
def _onboard_team(base_url, year_groups=None):
50+
if year_groups is None:
51+
year_groups = _year_groups
4152
onboarding = PointOfCareOnboarding.get_onboarding_data_for_tests(
4253
base_url=base_url,
43-
year_groups=_year_groups,
54+
year_groups=year_groups,
4455
)
4556
return _create_onboarding_with_retry(base_url, onboarding)
4657

@@ -122,6 +133,43 @@ def school_b(team_b):
122133
return team_b.schools[Programme.FLU.group][0]
123134

124135

136+
# Fixtures for consent breakdown test
137+
@pytest.fixture(scope="module")
138+
def consent_team_a(base_url):
139+
onboarding = _onboard_team(base_url, _year_groups_consent_a)
140+
yield onboarding
141+
_delete_team(base_url, onboarding.team)
142+
143+
144+
@pytest.fixture(scope="module")
145+
def consent_team_b(base_url):
146+
onboarding = _onboard_team(base_url, _year_groups_consent_b)
147+
yield onboarding
148+
_delete_team(base_url, onboarding.team)
149+
150+
151+
@pytest.fixture(scope="module")
152+
def consent_all_children():
153+
return [
154+
Child.generate(_yg_consent_a),
155+
Child.generate(_yg_consent_a),
156+
Child.generate(_yg_consent_a),
157+
Child.generate(_yg_consent_a),
158+
Child.generate(_yg_consent_b),
159+
Child.generate(_yg_consent_b),
160+
]
161+
162+
163+
@pytest.fixture(scope="module")
164+
def consent_school_a(consent_team_a):
165+
return consent_team_a.schools[Programme.FLU.group][0]
166+
167+
168+
@pytest.fixture(scope="module")
169+
def consent_school_b(consent_team_b):
170+
return consent_team_b.schools[Programme.FLU.group][0]
171+
172+
125173
def _do_setup(page, base_url, team_a, team_b, all_children, school_a, school_b):
126174
global _setup_complete # noqa: PLW0603
127175
if _setup_complete:
@@ -211,6 +259,97 @@ def _do_setup(page, base_url, team_a, team_b, all_children, school_a, school_b):
211259
_setup_complete = True
212260

213261

262+
def _do_consent_breakdown_setup(
263+
page, base_url, team_a, team_b, all_children, school_a, school_b
264+
):
265+
global _consent_breakdown_setup_complete # noqa: PLW0603
266+
if _consent_breakdown_setup_complete:
267+
return
268+
269+
c1, c2, c3, c4, c5, c6 = all_children
270+
two_mf = ClassFileMapping.REPORTING_REGRESSION_TWO_MF
271+
one_f = ClassFileMapping.REPORTING_REGRESSION_ONE_F
272+
273+
LogInPage(page).navigate()
274+
LogInPage(page).log_in_and_choose_team_if_necessary(
275+
team_a.users["nurse"], team_a.team
276+
)
277+
278+
_upload_class_list(page, school_a, team_a, [c1, c2], two_mf, _yg_consent_a)
279+
_upload_class_list(page, school_a, team_a, [c3, c4], two_mf, _yg_consent_a)
280+
281+
schedule_school_session_if_needed(
282+
page,
283+
school_a,
284+
[Programme.FLU],
285+
[_yg_consent_a],
286+
)
287+
session_id_a = SessionsOverviewPage(page).get_session_id_from_offline_excel()
288+
289+
team_a_vaccs_fg = _make_file_generator(team_a, [c1, c2, c3, c4])
290+
291+
SessionsOverviewPage(page).header.click_mavis()
292+
DashboardPage(page).click_imports()
293+
ImportsPage(page).click_upload_records()
294+
ImportRecordsWizardPage(
295+
page, team_a_vaccs_fg
296+
).navigate_to_vaccination_records_import()
297+
ImportRecordsWizardPage(page, team_a_vaccs_fg).upload_and_verify_output(
298+
file_mapping=VaccsFileMapping.REPORTING_REGRESSION_TEAM_A,
299+
session_id=session_id_a,
300+
programme_group=Programme.FLU.group,
301+
)
302+
303+
LogOutPage(page).navigate()
304+
LogOutPage(page).verify_log_out_page()
305+
LogInPage(page).navigate()
306+
LogInPage(page).log_in_and_choose_team_if_necessary(
307+
team_b.users["nurse"], team_b.team
308+
)
309+
310+
_upload_class_list(page, school_b, team_b, [c2], one_f, _yg_consent_a)
311+
_upload_class_list(page, school_b, team_b, [c4], one_f, _yg_consent_a)
312+
_upload_class_list(page, school_b, team_b, [c5, c6], two_mf, _yg_consent_b)
313+
314+
schedule_school_session_if_needed(
315+
page,
316+
school_b,
317+
[Programme.FLU],
318+
[_yg_consent_a, _yg_consent_b],
319+
)
320+
session_id_b = SessionsOverviewPage(page).get_session_id_from_offline_excel()
321+
322+
team_b_vaccs_fg = _make_file_generator(team_b, [c5, c6])
323+
324+
SessionsOverviewPage(page).header.click_mavis()
325+
DashboardPage(page).click_imports()
326+
ImportsPage(page).click_upload_records()
327+
ImportRecordsWizardPage(
328+
page, team_b_vaccs_fg
329+
).navigate_to_vaccination_records_import()
330+
ImportRecordsWizardPage(page, team_b_vaccs_fg).upload_and_verify_output(
331+
file_mapping=VaccsFileMapping.REPORTING_REGRESSION_TEAM_B,
332+
session_id=session_id_b,
333+
programme_group=Programme.FLU.group,
334+
)
335+
336+
ImportsPage(page).header.click_mavis()
337+
DashboardPage(page).click_school_moves()
338+
339+
SchoolMovesPage(page).click_child(c2)
340+
ReviewSchoolMovePage(page).confirm()
341+
342+
SchoolMovesPage(page).click_child(c4)
343+
ReviewSchoolMovePage(page).confirm()
344+
345+
_refresh_reporting(base_url)
346+
347+
LogOutPage(page).navigate()
348+
LogOutPage(page).verify_log_out_page()
349+
350+
_consent_breakdown_setup_complete = True
351+
352+
214353
def test_team_a_reporting(
215354
page,
216355
base_url,
@@ -478,3 +617,71 @@ def test_team_b_aggregate_csv(
478617
assert yg3_f["Cohort"] == 1
479618
assert yg3_f["Vaccinated"] == 0
480619
assert yg3_f["Not Vaccinated"] == 1
620+
621+
622+
def test_consent_breakdown_counts_add_up(
623+
page,
624+
base_url,
625+
consent_team_a,
626+
consent_team_b,
627+
consent_all_children,
628+
consent_school_a,
629+
consent_school_b,
630+
):
631+
"""
632+
Test: Verify consent report breakdown counts add up to total.
633+
Steps:
634+
1. Setup with single year group for consent breakdown test.
635+
2. Log in as Team A nurse.
636+
3. Navigate to Reports > Consent tab.
637+
4. Get counts from "No consent recorded" box and breakdown boxes.
638+
5. Verify breakdown counts add up to total.
639+
Verification:
640+
- Sum of breakdown boxes equals "No consent recorded" total.
641+
- Handles cases where some breakdown boxes may not exist.
642+
"""
643+
_do_consent_breakdown_setup(
644+
page,
645+
base_url,
646+
consent_team_a,
647+
consent_team_b,
648+
consent_all_children,
649+
consent_school_a,
650+
consent_school_b,
651+
)
652+
653+
page.context.clear_cookies()
654+
LogInPage(page).navigate()
655+
LogInPage(page).log_in_and_choose_team_if_necessary(
656+
consent_team_a.users["nurse"], consent_team_a.team
657+
)
658+
659+
ReportsConsentPage(page).navigate()
660+
ReportsConsentPage(page).check_filter_for_programme(Programme.FLU)
661+
662+
# Get the total from "No consent recorded" box
663+
no_consent_total = ReportsConsentPage(page).get_children_count(
664+
"No consent recorded"
665+
)
666+
667+
# Get counts from the three breakdown boxes
668+
# Note: These box names will need to be verified against actual UI
669+
breakdown_box_1 = ReportsConsentPage(page).get_children_count(
670+
"No consent response or not yet invited"
671+
)
672+
breakdown_box_2 = ReportsConsentPage(page).get_children_count("Consent refused")
673+
674+
# Try to get the third breakdown box, but it may not exist
675+
# if no children have that status
676+
try:
677+
breakdown_box_3 = ReportsConsentPage(page).get_children_count(
678+
"No response - follow-up requested"
679+
)
680+
except PlaywrightTimeoutError:
681+
breakdown_box_3 = 0
682+
683+
# Verify the breakdown counts add up to the total
684+
breakdown_sum = breakdown_box_1 + breakdown_box_2 + breakdown_box_3
685+
assert breakdown_sum == no_consent_total, (
686+
f"Breakdown sum ({breakdown_sum}) does not match total ({no_consent_total})"
687+
)

0 commit comments

Comments
 (0)