Skip to content

Commit 388f04d

Browse files
authored
Eli 783/extract override from actions (#637)
* updated action rule handler and implemented tests * updated extract status text override method to allow empty list aswell as None to allow integration test to pass * fixed linting issue
1 parent 54d5ee7 commit 388f04d

3 files changed

Lines changed: 116 additions & 3 deletions

File tree

src/eligibility_signposting_api/services/processors/action_rule_handler.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from itertools import groupby
22
from operator import attrgetter
33

4+
from eligibility_signposting_api.config.constants import STATUS_TEXT_OVERRIDE_ACTION_TYPE
45
from eligibility_signposting_api.model.campaign_config import (
56
ActionsMapper,
67
Iteration,
@@ -14,6 +15,7 @@
1415
IterationResult,
1516
MatchedActionDetail,
1617
RuleType,
18+
StatusText,
1719
SuggestedAction,
1820
UrlLabel,
1921
UrlLink,
@@ -65,7 +67,11 @@ def _handle(self, person: Person, best_active_iteration: Iteration, rule_type: R
6567
matched_action_rule_name = rule_group_list[0].name
6668
break
6769

68-
return MatchedActionDetail(matched_action_rule_name, matched_action_rule_priority, actions)
70+
actions, status_text_override = self._extract_status_text_override(actions)
71+
72+
return MatchedActionDetail(
73+
matched_action_rule_name, matched_action_rule_priority, actions, status_text_override
74+
)
6975

7076
@staticmethod
7177
def _get_action_rules_components(
@@ -102,3 +108,23 @@ def _get_actions_from_comms(action_mapper: ActionsMapper, comms: str) -> list[Su
102108
)
103109
)
104110
return suggested_actions
111+
112+
@staticmethod
113+
def _extract_status_text_override(
114+
actions: list[SuggestedAction] | None,
115+
) -> tuple[list[SuggestedAction] | None, StatusText | None]:
116+
if actions is None:
117+
return None, None
118+
119+
if len(actions) == 0:
120+
return [], None
121+
122+
override_text = None
123+
remaining = []
124+
for action in actions:
125+
if action.action_type == STATUS_TEXT_OVERRIDE_ACTION_TYPE:
126+
override_text = StatusText(str(action.action_description)) if action.action_description else None
127+
else:
128+
remaining.append(action)
129+
130+
return remaining, override_text

tests/unit/model/test_status.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ def test_matched_action_detail_existing_constructor_still_works_with_three_args(
8080
rule_name=RuleName("RuleA"),
8181
rule_priority=RulePriority(1),
8282
actions=actions,
83-
status_text_override=StatusText(None),
83+
status_text_override=None,
8484
),
8585
)
8686

tests/unit/services/processors/test_action_rule_handler.py

Lines changed: 88 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
from unittest.mock import Mock, call, patch
22

33
import pytest
4-
from hamcrest import assert_that, is_
4+
from hamcrest import assert_that, has_properties, is_
55
from pydantic import HttpUrl
66

7+
from eligibility_signposting_api.config.constants import STATUS_TEXT_OVERRIDE_ACTION_TYPE
78
from eligibility_signposting_api.model.campaign_config import AvailableAction, RuleName, RulePriority, RuleType
89
from eligibility_signposting_api.model.eligibility_status import (
910
ActionCode,
@@ -812,3 +813,89 @@ def test_handle_is_not_called_when_include_actions_is_false(mock_handle, handler
812813
)
813814

814815
assert_that(mock_handle.call_count, is_(0))
816+
817+
818+
def _make_action(action_type: str, description: str) -> SuggestedAction:
819+
return SuggestedAction(
820+
action_type=ActionType(action_type),
821+
action_code=ActionCode("CODE"),
822+
action_description=ActionDescription(description),
823+
url_link=None,
824+
url_label=None,
825+
internal_action_code=InternalActionCode("code"),
826+
)
827+
828+
829+
REGULAR_ACTION = _make_action("CareCardWithText", "You are eligible for a vaccination")
830+
OVERRIDE_ACTION = _make_action(STATUS_TEXT_OVERRIDE_ACTION_TYPE, "You maybe eligible for a vaccination")
831+
832+
833+
def test_extract_status_text_override_with_none_returns_none_none():
834+
result = ActionRuleHandler._extract_status_text_override(None)
835+
836+
assert_that(result, is_((None, None)))
837+
838+
839+
def test_extract_status_text_override_with_empty_list_returns_none_none():
840+
result = ActionRuleHandler._extract_status_text_override([])
841+
842+
assert_that(result, is_(([], None)))
843+
844+
845+
def test_extract_status_text_override_with_no_override_action_leaves_actions_unchanged():
846+
actions = [REGULAR_ACTION]
847+
848+
remaining, override_text = ActionRuleHandler._extract_status_text_override(actions)
849+
850+
assert_that(remaining, is_([REGULAR_ACTION]))
851+
assert_that(override_text, is_(None))
852+
853+
854+
def test_extract_status_text_override_with_only_override_action_captures_text():
855+
actions = [OVERRIDE_ACTION]
856+
857+
remaining, override_text = ActionRuleHandler._extract_status_text_override(actions)
858+
859+
assert_that(remaining, is_([]))
860+
assert_that(override_text, is_(StatusText("You maybe eligible for a vaccination")))
861+
862+
863+
def test_extract_status_text_override_with_mixed_actions_strips_override_and_keeps_others():
864+
actions = [REGULAR_ACTION, OVERRIDE_ACTION]
865+
866+
remaining, override_text = ActionRuleHandler._extract_status_text_override(actions)
867+
868+
assert_that(remaining, is_([REGULAR_ACTION]))
869+
assert_that(override_text, is_(StatusText("You maybe eligible for a vaccination")))
870+
871+
872+
@patch.object(ActionRuleHandler, "_get_actions_from_comms")
873+
@patch.object(ActionRuleHandler, "_get_action_rules_components")
874+
def test_handle_returns_status_text_override_in_matched_action_detail(
875+
mock_get_action_rules_components,
876+
mock_get_actions_from_comms,
877+
handler: ActionRuleHandler,
878+
):
879+
active_iteration = rule_builder.IterationFactory.build(
880+
default_comms_routing="default_action_code",
881+
actions_mapper=ActionsMapperFactory.build(),
882+
iteration_rules=[],
883+
)
884+
mock_get_action_rules_components.return_value = (
885+
[],
886+
active_iteration.actions_mapper,
887+
active_iteration.default_comms_routing,
888+
)
889+
mock_get_actions_from_comms.return_value = [REGULAR_ACTION, OVERRIDE_ACTION]
890+
891+
matched_action_detail = handler._handle(MOCK_PERSON, active_iteration, RuleType.redirect)
892+
893+
assert_that(
894+
matched_action_detail,
895+
has_properties(
896+
actions=[REGULAR_ACTION],
897+
status_text_override=StatusText("You maybe eligible for a vaccination"),
898+
rule_name=None,
899+
rule_priority=None,
900+
),
901+
)

0 commit comments

Comments
 (0)