Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@
IterationResult,
MatchedActionDetail,
RuleType,
StatusText,
SuggestedAction,
UrlLabel,
UrlLink,
)
from eligibility_signposting_api.model.person import Person
from eligibility_signposting_api.services.calculators.rule_calculator import RuleCalculator
from eligibility_signposting_api.config.constants import STATUS_TEXT_OVERRIDE_ACTION_TYPE


class ActionRuleHandler:
Expand Down Expand Up @@ -65,7 +67,9 @@ def _handle(self, person: Person, best_active_iteration: Iteration, rule_type: R
matched_action_rule_name = rule_group_list[0].name
break

return MatchedActionDetail(matched_action_rule_name, matched_action_rule_priority, actions)
actions, status_text_override = self._extract_status_text_override(actions)

return MatchedActionDetail(matched_action_rule_name, matched_action_rule_priority, actions, status_text_override)

@staticmethod
def _get_action_rules_components(
Expand Down Expand Up @@ -102,3 +106,23 @@ def _get_actions_from_comms(action_mapper: ActionsMapper, comms: str) -> list[Su
)
)
return suggested_actions

@staticmethod
def _extract_status_text_override(
actions: list[SuggestedAction] | None,
) -> tuple[list[SuggestedAction] | None, StatusText | None]:
if actions is None:
return None, None

if len(actions) == 0:
return [], None

override_text = None
remaining = []
Comment thread
oneeb-nhs marked this conversation as resolved.
for action in actions:
if action.action_type == STATUS_TEXT_OVERRIDE_ACTION_TYPE:
override_text = StatusText(str(action.action_description)) if action.action_description else None
else:
remaining.append(action)

return remaining, override_text
2 changes: 1 addition & 1 deletion tests/unit/model/test_status.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ def test_matched_action_detail_existing_constructor_still_works_with_three_args(
rule_name=RuleName("RuleA"),
rule_priority=RulePriority(1),
actions=actions,
status_text_override=StatusText(None),
status_text_override=None,
),
)

Expand Down
97 changes: 96 additions & 1 deletion tests/unit/services/processors/test_action_rule_handler.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
from unittest.mock import Mock, call, patch

import pytest
from hamcrest import assert_that, is_
from hamcrest import assert_that, has_properties, is_
from pydantic import HttpUrl

from eligibility_signposting_api.config.constants import STATUS_TEXT_OVERRIDE_ACTION_TYPE
from eligibility_signposting_api.model.campaign_config import AvailableAction, RuleName, RulePriority, RuleType
from eligibility_signposting_api.model.eligibility_status import (
ActionCode,
Expand Down Expand Up @@ -812,3 +813,97 @@ def test_handle_is_not_called_when_include_actions_is_false(mock_handle, handler
)

assert_that(mock_handle.call_count, is_(0))


# --- helpers ---

def _make_action(action_type: str, description: str) -> SuggestedAction:
return SuggestedAction(
action_type=ActionType(action_type),
action_code=ActionCode("CODE"),
action_description=ActionDescription(description),
url_link=None,
url_label=None,
internal_action_code=InternalActionCode("code"),
)


REGULAR_ACTION = _make_action("CareCardWithText", "You are eligible for a vaccination")
OVERRIDE_ACTION = _make_action(STATUS_TEXT_OVERRIDE_ACTION_TYPE, "You maybe eligible for a vaccination")


# --- _extract_status_text_override ---

def test_extract_status_text_override_with_none_returns_none_none():
result = ActionRuleHandler._extract_status_text_override(None)

assert_that(result, is_((None, None)))


def test_extract_status_text_override_with_empty_list_returns_none_none():
result = ActionRuleHandler._extract_status_text_override([])

assert_that(result, is_(([], None)))


def test_extract_status_text_override_with_no_override_action_leaves_actions_unchanged():
actions = [REGULAR_ACTION]

remaining, override_text = ActionRuleHandler._extract_status_text_override(actions)

assert_that(remaining, is_([REGULAR_ACTION]))
assert_that(override_text, is_(None))


def test_extract_status_text_override_with_only_override_action_captures_text():
actions = [OVERRIDE_ACTION]

remaining, override_text = ActionRuleHandler._extract_status_text_override(actions)

assert_that(remaining, is_([]))
assert_that(override_text, is_(StatusText("You maybe eligible for a vaccination")))


def test_extract_status_text_override_with_mixed_actions_strips_override_and_keeps_others():
actions = [REGULAR_ACTION, OVERRIDE_ACTION]

remaining, override_text = ActionRuleHandler._extract_status_text_override(actions)

assert_that(remaining, is_([REGULAR_ACTION]))
assert_that(override_text, is_(StatusText("You maybe eligible for a vaccination")))


# --- _handle integration ---

@patch("eligibility_signposting_api.services.processors.action_rule_handler.RuleCalculator")
@patch.object(ActionRuleHandler, "_get_actions_from_comms")
@patch.object(ActionRuleHandler, "_get_action_rules_components")
def test_handle_returns_status_text_override_in_matched_action_detail(
mock_get_action_rules_components,
mock_get_actions_from_comms,
mock_rule_calculator_class,
handler: ActionRuleHandler,
):
active_iteration = rule_builder.IterationFactory.build(
default_comms_routing="default_action_code",
actions_mapper=ActionsMapperFactory.build(),
iteration_rules=[],
)
mock_get_action_rules_components.return_value = (
[],
active_iteration.actions_mapper,
active_iteration.default_comms_routing,
)
mock_get_actions_from_comms.return_value = [REGULAR_ACTION, OVERRIDE_ACTION]

matched_action_detail = handler._handle(MOCK_PERSON, active_iteration, RuleType.redirect)

assert_that(
matched_action_detail,
has_properties(
actions=[REGULAR_ACTION],
status_text_override=StatusText("You maybe eligible for a vaccination"),
rule_name=None,
rule_priority=None,
),
)
Loading