- {% if is_case_complete %}
-
Response status
- {% else %}
-
Change response status
- {% endif %}
+
Change response status
{{
onsMetadata({
"termCol": "3",
@@ -92,30 +88,15 @@
Change response status
]
})
}}
- {% if is_case_complete %}
-
Close
- {% else %}
-
{% endif %}
diff --git a/response_operations_ui/views/case.py b/response_operations_ui/views/case.py
index fcea91573..1dec2aa7f 100644
--- a/response_operations_ui/views/case.py
+++ b/response_operations_ui/views/case.py
@@ -10,6 +10,7 @@
format_short_name,
map_ce_response_status,
)
+from response_operations_ui.contexts.case import build_response_status_context
from response_operations_ui.controllers import (
case_controller,
collection_exercise_controllers,
@@ -23,6 +24,7 @@
from response_operations_ui.controllers.party_controller import (
get_respondent_by_party_id,
)
+from response_operations_ui.controllers.uaa_controller import user_has_permission
from response_operations_ui.forms import ChangeGroupStatusForm
ALLOWED_TRANSITIONS = ["COMPLETEDBYPHONE", "NOLONGERREQUIRED", "NOTSTARTED"]
@@ -74,6 +76,17 @@ def get_response_statuses(ru_ref, error=None):
if status in allowed_transitions_filtered
}
+ has_reporting_unit_permission = user_has_permission("reportingunits.edit")
+ context = build_response_status_context(
+ ru_ref,
+ format_short_name(survey["shortName"]),
+ case_group["id"],
+ period,
+ allowed_transitions_for_case,
+ survey["id"],
+ has_reporting_unit_permission,
+ )
+
return render_template(
"response-status.html",
ru_ref=ru_ref,
@@ -90,6 +103,7 @@ def get_response_statuses(ru_ref, error=None):
is_case_complete=is_case_complete,
completed_timestamp=completed_timestamp,
completed_respondent=completed_respondent,
+ context=context,
)
diff --git a/response_operations_ui/views/reporting_units.py b/response_operations_ui/views/reporting_units.py
index e5e642ff5..f3860227e 100644
--- a/response_operations_ui/views/reporting_units.py
+++ b/response_operations_ui/views/reporting_units.py
@@ -10,6 +10,9 @@
from response_operations_ui.common.mappers import map_ce_response_status, map_region
from response_operations_ui.common.pagination_processor import pagination_processor
+from response_operations_ui.contexts.reporting_units import (
+ build_reporting_units_context,
+)
from response_operations_ui.controllers import (
case_controller,
iac_controller,
@@ -22,6 +25,7 @@
get_collection_exercise_by_id,
)
from response_operations_ui.controllers.survey_controllers import get_survey_by_id
+from response_operations_ui.controllers.uaa_controller import user_has_permission
from response_operations_ui.exceptions.exceptions import ApiError
from response_operations_ui.forms import EditContactDetailsForm, RuSearchForm
@@ -211,6 +215,20 @@ def view_reporting_unit_survey(ru_ref, survey_id):
logger.info("Successfully gathered data to view reporting unit survey data", ru_ref=ru_ref, survey_id=survey_id)
+ permissions = {
+ "reporting_unit_edit": user_has_permission("reportingunits.edit"),
+ "messages_edit": user_has_permission("messages.edit"),
+ }
+ context = build_reporting_units_context(
+ collection_exercises_with_details,
+ reporting_unit,
+ survey_details,
+ survey_respondents,
+ case,
+ unused_iac,
+ permissions,
+ )
+
return render_template(
"reporting-unit-survey.html",
ru=reporting_unit,
@@ -219,6 +237,7 @@ def view_reporting_unit_survey(ru_ref, survey_id):
collection_exercises=collection_exercises_with_details,
iac=unused_iac,
case=case,
+ context=context,
)
diff --git a/tests/context/conftest.py b/tests/context/conftest.py
index a1e9f4e2b..967fda9c5 100644
--- a/tests/context/conftest.py
+++ b/tests/context/conftest.py
@@ -242,3 +242,328 @@ def ce_details_dynamic_event_deleted(ce_details_dynamic_event):
ce_details_dynamic_event_deleted = ce_details_dynamic_event.copy()
del ce_details_dynamic_event_deleted["events"]["reminder2"]
return ce_details_dynamic_event_deleted
+
+
+@pytest.fixture()
+def collection_exercises_with_details(ce_details):
+ collection_exercises_with_details = ce_details["collection_exercise"].copy()
+ collection_exercises_with_details["responseStatus"] = "Not started"
+ collection_exercises_with_details["companyName"] = "RUNAME1_COMPANY1 RUNNAME2_COMPANY1 "
+ collection_exercises_with_details["companyRegion"] = "GB"
+ collection_exercises_with_details["tradingAs"] = "TOTAL UK ACTIVITY "
+ return [collection_exercises_with_details]
+
+
+@pytest.fixture
+def in_progress_collection_exercise_with_details(collection_exercises_with_details):
+ in_progress_collection_exercise = collection_exercises_with_details.copy()
+ in_progress_collection_exercise[0]["responseStatus"] = "In progress"
+ return in_progress_collection_exercise
+
+
+@pytest.fixture
+def completed_collection_exercise_with_details(collection_exercises_with_details):
+ completed_progress_collection_exercise = collection_exercises_with_details.copy()
+ completed_progress_collection_exercise[0]["responseStatus"] = "Completed"
+ return completed_progress_collection_exercise
+
+
+@pytest.fixture
+def no_longer_required_collection_exercise_with_details(collection_exercises_with_details):
+ no_longer_required_collection_exercise = collection_exercises_with_details.copy()
+ no_longer_required_collection_exercise[0]["responseStatus"] = "No longer required"
+ return no_longer_required_collection_exercise
+
+
+@pytest.fixture
+def error_collection_exercise_with_details(collection_exercises_with_details):
+ error_collection_exercise_with_details = collection_exercises_with_details.copy()
+ error_collection_exercise_with_details[0]["responseStatus"] = "Error"
+ return error_collection_exercise_with_details
+
+
+@pytest.fixture
+def multiple_collection_exercises_with_details(collection_exercises_with_details):
+ multiple_collection_exercises_with_details = collection_exercises_with_details.copy()
+ multiple_collection_exercises_with_details.append(collection_exercises_with_details[0].copy())
+ multiple_collection_exercises_with_details[1]["responseStatus"] = "In progress"
+ return multiple_collection_exercises_with_details
+
+
+@pytest.fixture()
+def reporting_unit():
+ return {
+ "associations": [
+ {
+ "businessRespondentStatus": "ACTIVE",
+ "enrolments": [{"enrolmentStatus": "ENABLED", "surveyId": "02b9c366-7397-42f7-942a-76dc5876d86d"}],
+ "partyId": "bf19a18f-fe15-4005-b698-fdd36f35f940",
+ }
+ ],
+ "id": "a5348157-feb4-4bad-9614-fc76e2bfea94",
+ "name": "RUNAME1_COMPANY1 RUNNAME2_COMPANY1",
+ "sampleSummaryId": "d646f19b-827f-4934-a71a-43ba458045b6",
+ "sampleUnitRef": "49900000001",
+ "sampleUnitType": "B",
+ "trading_as": "TOTAL UK ACTIVITY",
+ }
+
+
+@pytest.fixture
+def multiple_reporting_units(reporting_unit):
+ multiple_reporting_units = reporting_unit.copy()
+ multiple_reporting_units["associations"].append(
+ {
+ "businessRespondentStatus": "ACTIVE",
+ "enrolments": [{"enrolmentStatus": "ENABLED", "surveyId": "02b9c366-7397-42f7-942a-76dc5876d86d"}],
+ "partyId": "985bf97e-4f03-4898-92ef-dd7aac23ab08",
+ },
+ )
+ return multiple_reporting_units
+
+
+@pytest.fixture()
+def survey_details(ce_details):
+ survey_details = ce_details["survey"].copy()
+ return survey_details
+
+
+@pytest.fixture()
+def survey_respondents():
+ return [
+ {
+ "associations": [
+ {
+ "businessRespondentStatus": "ACTIVE",
+ "enrolments": [{"enrolmentStatus": "ENABLED", "surveyId": "02b9c366-7397-42f7-942a-76dc5876d86d"}],
+ "partyId": "a5348157-feb4-4bad-9614-fc76e2bfea94",
+ "sampleUnitRef": "49900000001",
+ }
+ ],
+ "emailAddress": "example@example.com",
+ "firstName": "john",
+ "id": "bf19a18f-fe15-4005-b698-fdd36f35f940",
+ "lastName": "doe",
+ "sampleUnitType": "BI",
+ "status": "ACTIVE",
+ "telephone": "07772257772",
+ "enrolmentStatus": "ENABLED",
+ }
+ ]
+
+
+@pytest.fixture
+def multiple_survey_respondents(survey_respondents):
+ multiple_survey_respondents = survey_respondents.copy()
+ multiple_survey_respondents.append(survey_respondents[0].copy())
+ return multiple_survey_respondents
+
+
+@pytest.fixture
+def suspended_survey_respondents(survey_respondents):
+ suspended_survey_respondents = survey_respondents.copy()
+ suspended_survey_respondents[0]["status"] = "SUSPENDED"
+ return suspended_survey_respondents
+
+
+@pytest.fixture
+def pending_enrolment_survey_respondents(survey_respondents):
+ pending_enrolment_survey_respondents = survey_respondents.copy()
+ pending_enrolment_survey_respondents[0]["enrolmentStatus"] = "PENDING"
+ return pending_enrolment_survey_respondents
+
+
+@pytest.fixture
+def disabled_enrolment_survey_respondents(survey_respondents):
+ disabled_enrolment_survey_respondents = survey_respondents.copy()
+ disabled_enrolment_survey_respondents[0]["enrolmentStatus"] = "DISABLED"
+ return disabled_enrolment_survey_respondents
+
+
+@pytest.fixture()
+def case():
+ return {
+ "state": "ACTIONABLE",
+ "id": "f4056be6-2581-4308-b7cd-88118325e81d",
+ "actionPlanId": None,
+ "activeEnrolment": True,
+ "collectionInstrumentId": "e726f50c-504c-4958-be96-9d77520746b9",
+ "partyId": "a5348157-feb4-4bad-9614-fc76e2bfea94",
+ "sampleUnitId": "d8579750-8817-4a58-8fa5-867f1447e1cc",
+ "iac": "t7jk7l29hymx",
+ "caseRef": "1000000000000003",
+ "createdBy": "SYSTEM",
+ "sampleUnitType": "B",
+ "createdDateTime": "2024-02-08T11:39:58.199Z",
+ "caseGroup": {
+ "collectionExerciseId": "1012f36c-b352-431c-b0c9-e7f435cbdd0c",
+ "id": "39c7e488-3f06-4ea9-82fb-3c619f362cb6",
+ "partyId": "a5348157-feb4-4bad-9614-fc76e2bfea94",
+ "sampleUnitRef": "49900000001",
+ "sampleUnitType": "B",
+ "caseGroupStatus": "NOTSTARTED",
+ "surveyId": "02b9c366-7397-42f7-942a-76dc5876d86d",
+ },
+ "caseEvents": None,
+ }
+
+
+@pytest.fixture()
+def unused_iac():
+ return "p79j76f4pwfg"
+
+
+@pytest.fixture
+def expected_ru_context_with_all_permissions():
+ return {
+ "collection_exercise_section": [
+ {
+ "hyperlink": "/case/49900000001/response-status?survey=MWSS&period=021123",
+ "hyperlink_text": "Change",
+ "period": "021123",
+ "region": "GB",
+ "reporting_unit_name": "RUNAME1_COMPANY1 " "RUNNAME2_COMPANY1 ",
+ "response_status": "Not started",
+ "status": {
+ "hyperlink": "/case/49900000001/response-status?survey=MWSS&period=021123",
+ "hyperlink_text": "Change",
+ "response_status": "Not started",
+ "status_class": "ons-status--info",
+ },
+ "status_class": "ons-status--info",
+ "trading_as": "TOTAL UK ACTIVITY ",
+ }
+ ],
+ "respondents_section": [
+ {
+ "account_status": "Active",
+ "account_status_class": "ons-status--success",
+ "contact_details": {"email": "example@example.com", "name": "john doe", "tel": "07772257772"},
+ "enrolment_code_hyperlink": "/reporting-units/49900000001/new_enrolment_code?"
+ + "case_id=f4056be6-2581-4308-b7cd-88118325e81d&"
+ + "collection_exercise_id=7702d7fd-f998-499d-a972-e2906b19e6cf&"
+ + "ru_name=RUNAME1_COMPANY1+RUNNAME2_COMPANY1&"
+ + "trading_as=TOTAL+UK+ACTIVITY++&survey_ref=134&survey_name=MWSS",
+ "enrolment_code_hyperlink_text": "Generate new " "enrollment code",
+ "enrolment_status": "Enabled",
+ "enrolment_status_class": "ons-status--success",
+ "enrolment_status_hyperlink": "/reporting-units/49900000001/change-enrolment-status?"
+ + "ru_name=RUNAME1_COMPANY1+RUNNAME2_COMPANY1&"
+ + "survey_id=c23bb1c1-5202-43bb-8357-7a07c844308f&survey_name=134&"
+ + "respondent_id=bf19a18f-fe15-4005-b698-fdd36f35f940&"
+ + "respondent_first_name=john&respondent_last_name=doe&"
+ + "business_id=a5348157-feb4-4bad-9614-fc76e2bfea94&"
+ + "trading_as=TOTAL+UK+ACTIVITY++&"
+ + "change_flag=DISABLED&tab=reporting_units",
+ "enrolment_status_hyperlink_text": "Disable",
+ "message": [
+ {"name": "ru_ref", "value": "49900000001"},
+ {"name": "business_id", "value": "a5348157-feb4-4bad-9614-fc76e2bfea94"},
+ {"name": "business", "value": "RUNAME1_COMPANY1 " "RUNNAME2_COMPANY1"},
+ {"name": "survey", "value": "MWSS"},
+ {"name": "survey_id", "value": "c23bb1c1-5202-43bb-8357-7a07c844308f"},
+ {"name": "msg_to_name", "value": "john doe"},
+ {"name": "msg_to", "value": "bf19a18f-fe15-4005-b698-fdd36f35f940"},
+ ],
+ }
+ ],
+ }
+
+
+@pytest.fixture
+def expected_ru_context_with_multiple_ces_and_respondents(expected_ru_context_with_all_permissions):
+ expected_ru_context_with_multiple_ces_and_respondents = expected_ru_context_with_all_permissions.copy()
+ expected_ru_context_with_multiple_ces_and_respondents["collection_exercise_section"].append(
+ {
+ "hyperlink": "/case/49900000001/response-status?survey=MWSS&period=021123",
+ "hyperlink_text": "Change",
+ "period": "021123",
+ "region": "GB",
+ "reporting_unit_name": "RUNAME1_COMPANY1 " "RUNNAME2_COMPANY1 ",
+ "response_status": "In progress",
+ "status": {
+ "hyperlink": "/case/49900000001/response-status?survey=MWSS&period=021123",
+ "hyperlink_text": "Change",
+ "response_status": "In progress",
+ "status_class": "ons-status--pending",
+ },
+ "status_class": "ons-status--pending",
+ "trading_as": "TOTAL UK ACTIVITY ",
+ }
+ )
+ expected_ru_context_with_multiple_ces_and_respondents["respondents_section"].append(
+ expected_ru_context_with_all_permissions["respondents_section"][0]
+ )
+ expected_ru_context_with_multiple_ces_and_respondents["respondents_section"][0].pop("enrolment_code_hyperlink")
+ expected_ru_context_with_multiple_ces_and_respondents["respondents_section"][0].pop("enrolment_code_hyperlink_text")
+ expected_ru_context_with_multiple_ces_and_respondents["respondents_section"][0]["enrolment_code"] = "99yk5r3yjycn"
+ return expected_ru_context_with_multiple_ces_and_respondents
+
+
+@pytest.fixture
+def expected_response_status_context_for_complete_case_with_all_permissions():
+ return {
+ "change_response_status": {
+ "cancel_link": "/reporting-units/49900000001/surveys/02b9c366-7397-42f7-942a-76dc5876d86d",
+ "radios": [{"id": "state-1", "label": {"text": "Not started"}, "value": "COMPLETED_TO_NOTSTARTED"}],
+ "url": "/case/49900000001/response-status?survey=QBS&"
+ + "case_group_id=6fef0397-f07b-4d65-8988-931cec23057f&period=1912",
+ }
+ }
+
+
+@pytest.fixture
+def expected_response_status_context_with_no_permissions():
+ return {"change_response_status": {}}
+
+
+@pytest.fixture
+def expected_response_status_context_transitions_for_incomplete_case(
+ expected_response_status_context_for_complete_case_with_all_permissions,
+):
+ expected_case_context_transitions_from_not_started = (
+ expected_response_status_context_for_complete_case_with_all_permissions.copy()
+ )
+ expected_case_context_transitions_from_not_started["change_response_status"]["radios"] = [
+ {"id": "state-1", "label": {"text": "Completed by phone"}, "value": "COMPLETED_BY_PHONE"},
+ {"id": "state-2", "label": {"text": "No longer required"}, "value": "NO_LONGER_REQUIRED"},
+ ]
+ return expected_case_context_transitions_from_not_started
+
+
+@pytest.fixture
+def transitions_for_complete_case():
+ return {"COMPLETED_TO_NOTSTARTED": "Not started"}
+
+
+@pytest.fixture
+def transitions_for_incomplete_case():
+ return {
+ "COMPLETED_BY_PHONE": "Completed by phone",
+ "NO_LONGER_REQUIRED": "No longer required",
+ }
+
+
+@pytest.fixture
+def ru_ref():
+ return "49900000001"
+
+
+@pytest.fixture
+def survey_short_name():
+ return "QBS"
+
+
+@pytest.fixture
+def case_group_id():
+ return "6fef0397-f07b-4d65-8988-931cec23057f"
+
+
+@pytest.fixture
+def ce_period():
+ return "1912"
+
+
+@pytest.fixture
+def survey_id():
+ return "02b9c366-7397-42f7-942a-76dc5876d86d"
diff --git a/tests/context/test_case_context.py b/tests/context/test_case_context.py
new file mode 100644
index 000000000..e94ffb8ca
--- /dev/null
+++ b/tests/context/test_case_context.py
@@ -0,0 +1,189 @@
+from response_operations_ui.contexts.case import build_response_status_context
+
+
+def test_response_status_context_with_permissions(
+ app,
+ transitions_for_complete_case,
+ expected_response_status_context_for_complete_case_with_all_permissions,
+ ru_ref,
+ survey_short_name,
+ case_group_id,
+ ce_period,
+ survey_id,
+):
+ with app.test_request_context():
+ context = build_response_status_context(
+ ru_ref,
+ survey_short_name,
+ case_group_id,
+ ce_period,
+ transitions_for_complete_case,
+ survey_id,
+ True,
+ )
+ assert context == expected_response_status_context_for_complete_case_with_all_permissions
+
+
+def test_response_status_context_without_permissions(
+ app,
+ transitions_for_complete_case,
+ expected_response_status_context_with_no_permissions,
+ ru_ref,
+ survey_short_name,
+ case_group_id,
+ ce_period,
+ survey_id,
+):
+ with app.test_request_context():
+ context = build_response_status_context(
+ ru_ref,
+ survey_short_name,
+ case_group_id,
+ ce_period,
+ transitions_for_complete_case,
+ survey_id,
+ False,
+ )
+ assert context == expected_response_status_context_with_no_permissions
+
+
+def test_transitions_from_not_started(
+ app,
+ transitions_for_incomplete_case,
+ expected_response_status_context_transitions_for_incomplete_case,
+ ru_ref,
+ survey_short_name,
+ case_group_id,
+ ce_period,
+ survey_id,
+):
+ with app.test_request_context():
+ context = build_response_status_context(
+ ru_ref,
+ survey_short_name,
+ case_group_id,
+ ce_period,
+ transitions_for_incomplete_case,
+ survey_id,
+ True,
+ )
+ radios = get_response_status_context(context, "change_response_status", "radios")
+
+ assert (
+ expected_response_status_context_transitions_for_incomplete_case["change_response_status"]["radios"] == radios
+ )
+
+
+def test_transitions_from_completed_by_phone(
+ app,
+ transitions_for_complete_case,
+ expected_response_status_context_for_complete_case_with_all_permissions,
+ ru_ref,
+ survey_short_name,
+ case_group_id,
+ ce_period,
+ survey_id,
+):
+ with app.test_request_context():
+ context = build_response_status_context(
+ ru_ref,
+ survey_short_name,
+ case_group_id,
+ ce_period,
+ transitions_for_complete_case,
+ survey_id,
+ True,
+ )
+ radios = get_response_status_context(context, "change_response_status", "radios")
+
+ assert (
+ expected_response_status_context_for_complete_case_with_all_permissions["change_response_status"]["radios"]
+ == radios
+ )
+
+
+def test_transitions_from_no_longer_required(
+ app,
+ transitions_for_complete_case,
+ expected_response_status_context_for_complete_case_with_all_permissions,
+ ru_ref,
+ survey_short_name,
+ case_group_id,
+ ce_period,
+ survey_id,
+):
+ with app.test_request_context():
+ context = build_response_status_context(
+ ru_ref,
+ survey_short_name,
+ case_group_id,
+ ce_period,
+ transitions_for_complete_case,
+ survey_id,
+ True,
+ )
+ radios = get_response_status_context(context, "change_response_status", "radios")
+
+ assert (
+ expected_response_status_context_for_complete_case_with_all_permissions["change_response_status"]["radios"]
+ == radios
+ )
+
+
+def test_transitions_from_in_progress(
+ app,
+ transitions_for_incomplete_case,
+ expected_response_status_context_transitions_for_incomplete_case,
+ ru_ref,
+ survey_short_name,
+ case_group_id,
+ ce_period,
+ survey_id,
+):
+ with app.test_request_context():
+ context = build_response_status_context(
+ ru_ref,
+ survey_short_name,
+ case_group_id,
+ ce_period,
+ transitions_for_incomplete_case,
+ survey_id,
+ True,
+ )
+ radios = get_response_status_context(context, "change_response_status", "radios")
+
+ assert (
+ expected_response_status_context_transitions_for_incomplete_case["change_response_status"]["radios"] == radios
+ )
+
+
+def test_transitions_from_complete(
+ app,
+ transitions_for_complete_case,
+ expected_response_status_context_for_complete_case_with_all_permissions,
+ ru_ref,
+ survey_short_name,
+ case_group_id,
+ ce_period,
+ survey_id,
+):
+ with app.test_request_context():
+ context = build_response_status_context(
+ ru_ref,
+ survey_short_name,
+ case_group_id,
+ ce_period,
+ transitions_for_complete_case,
+ survey_id,
+ True,
+ )
+ radios = get_response_status_context(context, "change_response_status", "radios")
+
+ assert (
+ expected_response_status_context_for_complete_case_with_all_permissions["change_response_status"]["radios"]
+ == radios
+ )
+
+
+def get_response_status_context(context, section, element):
+ return context[section][element]
diff --git a/tests/context/test_reporting_units_context.py b/tests/context/test_reporting_units_context.py
new file mode 100644
index 000000000..b88345b80
--- /dev/null
+++ b/tests/context/test_reporting_units_context.py
@@ -0,0 +1,295 @@
+from response_operations_ui.contexts.reporting_units import (
+ build_reporting_units_context,
+)
+
+
+def test_has_both_edit_permission(
+ app,
+ collection_exercises_with_details,
+ reporting_unit,
+ survey_details,
+ survey_respondents,
+ case,
+ expected_ru_context_with_all_permissions,
+):
+ with app.test_request_context():
+ context = build_reporting_units_context(
+ collection_exercises_with_details,
+ reporting_unit,
+ survey_details,
+ survey_respondents,
+ case,
+ "",
+ {"reporting_unit_edit": True, "messages_edit": True},
+ )
+ hyperlink = get_ru_context(context, "collection_exercise_section", 0, "status")["hyperlink_text"]
+ message = get_ru_context(context, "respondents_section", 0, "message")
+
+ assert context == expected_ru_context_with_all_permissions
+ assert "Change" in hyperlink
+ assert message[0]["value"] == "49900000001"
+
+
+def test_no_reporting_units_edit_permission(
+ app,
+ collection_exercises_with_details,
+ reporting_unit,
+ survey_details,
+ survey_respondents,
+ case,
+):
+ with app.test_request_context():
+ context = build_reporting_units_context(
+ collection_exercises_with_details,
+ reporting_unit,
+ survey_details,
+ survey_respondents,
+ case,
+ "",
+ {"reporting_unit_edit": False, "messages_edit": True},
+ )
+ hyperlink = get_ru_context(context, "collection_exercise_section", 0, "status")["hyperlink_text"]
+
+ assert "Change" not in hyperlink
+ assert "View" in hyperlink
+
+
+def test_no_messages_edit_permission(
+ app,
+ collection_exercises_with_details,
+ reporting_unit,
+ survey_details,
+ survey_respondents,
+ case,
+):
+ with app.test_request_context():
+ context = build_reporting_units_context(
+ collection_exercises_with_details,
+ reporting_unit,
+ survey_details,
+ survey_respondents,
+ case,
+ "",
+ {"reporting_unit_edit": True, "messages_edit": False},
+ )
+
+ assert "message" not in context["respondents_section"][0].keys()
+
+
+def test_collection_exercise_in_progress(
+ app, in_progress_collection_exercise_with_details, reporting_unit, survey_details, survey_respondents, case
+):
+ with app.test_request_context():
+ context = build_reporting_units_context(
+ in_progress_collection_exercise_with_details,
+ reporting_unit,
+ survey_details,
+ survey_respondents,
+ case,
+ "",
+ {"reporting_unit_edit": True, "messages_edit": True},
+ )
+ collection_exercise_status = get_ru_context(context, "collection_exercise_section", 0, "status_class")
+
+ assert "ons-status--pending" in collection_exercise_status
+
+
+def test_collection_exercise_completed(
+ app, completed_collection_exercise_with_details, reporting_unit, survey_details, survey_respondents, case
+):
+ with app.test_request_context():
+ context = build_reporting_units_context(
+ completed_collection_exercise_with_details,
+ reporting_unit,
+ survey_details,
+ survey_respondents,
+ case,
+ "",
+ {"reporting_unit_edit": True, "messages_edit": True},
+ )
+ collection_exercise_status = get_ru_context(context, "collection_exercise_section", 0, "status_class")
+
+ assert "ons-status--success" in collection_exercise_status
+
+
+def test_collection_exercise_no_longer_required(
+ app, no_longer_required_collection_exercise_with_details, reporting_unit, survey_details, survey_respondents, case
+):
+ with app.test_request_context():
+ context = build_reporting_units_context(
+ no_longer_required_collection_exercise_with_details,
+ reporting_unit,
+ survey_details,
+ survey_respondents,
+ case,
+ "",
+ {"reporting_unit_edit": True, "messages_edit": True},
+ )
+ collection_exercise_status = get_ru_context(context, "collection_exercise_section", 0, "status_class")
+
+ assert "ons-status--dead" in collection_exercise_status
+
+
+def test_collection_exercise_error(
+ app, error_collection_exercise_with_details, reporting_unit, survey_details, survey_respondents, case
+):
+ with app.test_request_context():
+ context = build_reporting_units_context(
+ error_collection_exercise_with_details,
+ reporting_unit,
+ survey_details,
+ survey_respondents,
+ case,
+ "",
+ {"reporting_unit_edit": True, "messages_edit": True},
+ )
+ collection_exercise_status = get_ru_context(context, "collection_exercise_section", 0, "status_class")
+
+ assert "ons-status--error" in collection_exercise_status
+
+
+def test_respondent_active(
+ app,
+ collection_exercises_with_details,
+ reporting_unit,
+ survey_details,
+ survey_respondents,
+ case,
+ expected_ru_context_with_all_permissions,
+):
+ with app.test_request_context():
+ context = build_reporting_units_context(
+ collection_exercises_with_details,
+ reporting_unit,
+ survey_details,
+ survey_respondents,
+ case,
+ "",
+ {"reporting_unit_edit": True, "messages_edit": True},
+ )
+ respondent_status = get_ru_context(context, "respondents_section", 0, "account_status_class")
+
+ assert "ons-status--success" in respondent_status
+
+
+def test_respondent_suspended(
+ app,
+ collection_exercises_with_details,
+ reporting_unit,
+ survey_details,
+ suspended_survey_respondents,
+ case,
+ expected_ru_context_with_all_permissions,
+):
+ with app.test_request_context():
+ context = build_reporting_units_context(
+ collection_exercises_with_details,
+ reporting_unit,
+ survey_details,
+ suspended_survey_respondents,
+ case,
+ "",
+ {"reporting_unit_edit": True, "messages_edit": True},
+ )
+ respondent_status = get_ru_context(context, "respondents_section", 0, "account_status_class")
+
+ assert "ons-status--error" in respondent_status
+
+
+def test_respondent_enrolment_enabled(
+ app,
+ collection_exercises_with_details,
+ reporting_unit,
+ survey_details,
+ survey_respondents,
+ case,
+ expected_ru_context_with_all_permissions,
+):
+ with app.test_request_context():
+ context = build_reporting_units_context(
+ collection_exercises_with_details,
+ reporting_unit,
+ survey_details,
+ survey_respondents,
+ case,
+ "",
+ {"reporting_unit_edit": True, "messages_edit": True},
+ )
+ enrolment_status = get_ru_context(context, "respondents_section", 0, "enrolment_status_class")
+
+ assert "ons-status--success" in enrolment_status
+
+
+def test_respondent_enrolment_pending(
+ app,
+ collection_exercises_with_details,
+ reporting_unit,
+ survey_details,
+ pending_enrolment_survey_respondents,
+ case,
+ expected_ru_context_with_all_permissions,
+):
+ with app.test_request_context():
+ context = build_reporting_units_context(
+ collection_exercises_with_details,
+ reporting_unit,
+ survey_details,
+ pending_enrolment_survey_respondents,
+ case,
+ "",
+ {"reporting_unit_edit": True, "messages_edit": True},
+ )
+ enrolment_status = get_ru_context(context, "respondents_section", 0, "enrolment_status_class")
+
+ assert "ons-status--info" in enrolment_status
+
+
+def test_respondent_enrolment_disabled(
+ app,
+ collection_exercises_with_details,
+ reporting_unit,
+ survey_details,
+ disabled_enrolment_survey_respondents,
+ case,
+ expected_ru_context_with_all_permissions,
+):
+ with app.test_request_context():
+ context = build_reporting_units_context(
+ collection_exercises_with_details,
+ reporting_unit,
+ survey_details,
+ disabled_enrolment_survey_respondents,
+ case,
+ "",
+ {"reporting_unit_edit": True, "messages_edit": True},
+ )
+ enrolment_status = get_ru_context(context, "respondents_section", 0, "enrolment_status_class")
+
+ assert "ons-status--dead" in enrolment_status
+
+
+def test_multiple_collection_exercises_and_respondents(
+ app,
+ multiple_collection_exercises_with_details,
+ multiple_reporting_units,
+ survey_details,
+ multiple_survey_respondents,
+ case,
+ expected_ru_context_with_multiple_ces_and_respondents,
+):
+ with app.test_request_context():
+ context = build_reporting_units_context(
+ multiple_collection_exercises_with_details,
+ multiple_reporting_units,
+ survey_details,
+ multiple_survey_respondents,
+ case,
+ "99yk5r3yjycn",
+ {"reporting_unit_edit": True, "messages_edit": True},
+ )
+
+ assert context == expected_ru_context_with_multiple_ces_and_respondents
+
+
+def get_ru_context(context, section, index, cell):
+ return context[section][index][cell]
diff --git a/tests/views/test_change_response_status.py b/tests/views/test_change_response_status.py
index e31989849..e06b3e510 100644
--- a/tests/views/test_change_response_status.py
+++ b/tests/views/test_change_response_status.py
@@ -3,10 +3,12 @@
from unittest import TestCase
import fakeredis
+import jwt
import requests_mock
from config import TestingConfig
from response_operations_ui import create_app
+from tests.views.test_sign_in import url_sign_in_data
short_name = "BLOCKS"
survey_id = "cb0711c3-0ac8-41d3-ae0e-567e5ea1ef87"
@@ -32,8 +34,9 @@
url_get_case_by_case_group_id = f"{TestingConfig.CASE_URL}/cases/casegroupid/{case_group_id}"
url_get_case_events = f"{TestingConfig.CASE_URL}/cases/{case_id}/events"
get_respondent_by_id_url = f"{TestingConfig.PARTY_URL}/party-api/v1/respondents/id/{party_id}"
-project_root = os.path.dirname(os.path.dirname(__file__))
+url_permission_url = f"{TestingConfig.UAA_SERVICE_URL}/Users/test-id"
+project_root = os.path.dirname(os.path.dirname(__file__))
with open(f"{project_root}/test_data/survey/single_survey.json") as fp:
survey = json.load(fp)
@@ -60,12 +63,24 @@
with open(f"{project_root}/test_data/case/case_groups_list_no_longer_required.json") as fp:
case_groups_no_longer_required = json.load(fp)
+user_permission_reporting_unit_edit_json = {
+ "id": "5902656c-c41c-4b38-a294-0359e6aabe59",
+ "groups": [{"value": "f385f89e-928f-4a0f-96a0-4c48d9007cc3", "display": "reportingunits.edit", "type": "DIRECT"}],
+}
+
+user_permission_admin_json = {
+ "id": "5902656c-c41c-4b38-a294-0359e6aabe59",
+ "groups": [{"value": "f385f89e-928f-4a0f-96a0-4c48d9007cc3", "display": "users.admin", "type": "DIRECT"}],
+}
+
class TestChangeResponseStatus(TestCase):
def setUp(self):
self.app = create_app("TestingConfig")
+ payload = {"user_id": "test-id", "aud": "response_operations"}
self.client = self.app.test_client()
self.setup_data()
+ self.access_token = jwt.encode(payload, TestingConfig.UAA_PRIVATE_KEY, algorithm="RS256")
self.app.config["SESSION_REDIS"] = fakeredis.FakeStrictRedis(
host=self.app.config["REDIS_HOST"], port=self.app.config["FAKE_REDIS_PORT"], db=self.app.config["REDIS_DB"]
)
@@ -83,7 +98,10 @@ def setup_data(self):
@requests_mock.mock()
def test_get_available_status(self, mock_request):
+ mock_request.post(url_sign_in_data, json={"access_token": self.access_token}, status_code=201)
mock_request.get(url_get_survey_by_short_name, json=survey)
+ mock_request.get(url_permission_url, json=user_permission_reporting_unit_edit_json, status_code=200)
+ self.client.post("/sign-in", follow_redirects=True, data={"username": "user", "password": "pass"})
mock_request.get(url_get_collection_exercises_by_survey, json=collection_exercise_list)
mock_request.get(url_get_business_by_ru_ref, json=business_reporting_unit)
mock_request.get(url_get_available_case_group_statuses, json=self.statuses)
@@ -300,13 +318,17 @@ def test_respondent_name_not_in_metadata_for_completed_case_event(self, mock_req
@requests_mock.mock()
def test_not_started_status_is_present_for_completed_by_phone(self, mock_request):
+ mock_request.post(url_sign_in_data, json={"access_token": self.access_token}, status_code=201)
mock_request.get(url_get_survey_by_short_name, json=survey)
+ mock_request.get(url_permission_url, json=user_permission_reporting_unit_edit_json, status_code=200)
+ self.client.post("/sign-in", follow_redirects=True, data={"username": "user", "password": "pass"})
mock_request.get(url_get_collection_exercises_by_survey, json=collection_exercise_list)
mock_request.get(url_get_business_by_ru_ref, json=business_reporting_unit)
mock_request.get(url_get_available_case_group_statuses, json=self.statuses)
mock_request.get(url_get_case_groups_by_business_party_id, json=case_groups_completed_by_phone)
mock_request.get(url_get_case_events, json=case_events)
mock_request.get(url_get_case_by_case_group_id, json=[case])
+ mock_request.get(url_permission_url, json=user_permission_reporting_unit_edit_json, status_code=200)
response = self.client.get(f"/case/{ru_ref}/response-status?survey={short_name}&period={period}")
@@ -317,7 +339,10 @@ def test_not_started_status_is_present_for_completed_by_phone(self, mock_request
@requests_mock.mock()
def test_not_started_status_is_present_for_no_longer_required(self, mock_request):
+ mock_request.post(url_sign_in_data, json={"access_token": self.access_token}, status_code=201)
mock_request.get(url_get_survey_by_short_name, json=survey)
+ mock_request.get(url_permission_url, json=user_permission_reporting_unit_edit_json, status_code=200)
+ self.client.post("/sign-in", follow_redirects=True, data={"username": "user", "password": "pass"})
mock_request.get(url_get_collection_exercises_by_survey, json=collection_exercise_list)
mock_request.get(url_get_business_by_ru_ref, json=business_reporting_unit)
mock_request.get(url_get_available_case_group_statuses, json=self.statuses)
@@ -331,3 +356,24 @@ def test_not_started_status_is_present_for_no_longer_required(self, mock_request
self.assertEqual(response.status_code, 200)
self.assertIn(b"No longer required", data)
self.assertIn(b"Not started", data)
+
+ @requests_mock.mock()
+ def test_not_started_status_is_present_for_completed(self, mock_request):
+ mock_request.post(url_sign_in_data, json={"access_token": self.access_token}, status_code=201)
+ mock_request.get(url_get_survey_by_short_name, json=survey)
+ mock_request.get(url_permission_url, json=user_permission_reporting_unit_edit_json, status_code=200)
+ self.client.post("/sign-in", follow_redirects=True, data={"username": "user", "password": "pass"})
+ mock_request.get(url_get_collection_exercises_by_survey, json=collection_exercise_list)
+ mock_request.get(url_get_business_by_ru_ref, json=business_reporting_unit)
+ mock_request.get(url_get_available_case_group_statuses, json=self.statuses)
+ mock_request.get(url_get_case_groups_by_business_party_id, json=case_groups_completed)
+ mock_request.get(url_get_case_by_case_group_id, json=[case])
+ mock_request.get(url_get_case_events, json=case_events)
+ mock_request.get(get_respondent_by_id_url, json=respondent)
+
+ response = self.client.get(f"/case/{ru_ref}/response-status?survey={short_name}&period={period}")
+
+ data = response.data
+ self.assertEqual(response.status_code, 200)
+ self.assertIn(b"Completed", data)
+ self.assertIn(b"Not started", data)