Skip to content

Commit cd3eebc

Browse files
authored
ELI-441: Fix Sonar code smells (#358)
1 parent 56d5854 commit cd3eebc

File tree

2 files changed

+58
-38
lines changed

2 files changed

+58
-38
lines changed

src/eligibility_signposting_api/services/processors/action_rule_handler.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,14 @@ def _handle(self, person: Person, best_active_iteration: Iteration, rule_type: R
5050
matched_action_rule_priority, matched_action_rule_name = None, None
5151
for _, rule_group in groupby(sorted_rules_by_priority, key=priority_getter):
5252
rule_group_list = list(rule_group)
53-
matcher_matched_list = [
53+
54+
all_rules_matched = all(
5455
RuleCalculator(person=person, rule=rule).evaluate_exclusion()[1].matcher_matched
5556
for rule in rule_group_list
56-
]
57+
)
5758

5859
comms_routing = rule_group_list[0].comms_routing
59-
if comms_routing and all(matcher_matched_list):
60+
if comms_routing and all_rules_matched:
6061
rule_actions = self._get_actions_from_comms(action_mapper, comms_routing)
6162
if rule_actions and len(rule_actions) > 0:
6263
actions = rule_actions

src/eligibility_signposting_api/services/processors/token_processor.py

Lines changed: 54 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -71,45 +71,64 @@ def replace_token(text: str, person: Person) -> str:
7171

7272
pattern = r"\[\[.*?\]\]"
7373
all_tokens = re.findall(pattern, text, re.IGNORECASE)
74-
present_attributes = [attribute.get("ATTRIBUTE_TYPE") for attribute in person.data]
74+
present_attributes = {attribute.get("ATTRIBUTE_TYPE") for attribute in person.data}
7575

7676
for token in all_tokens:
77-
parsed_token = TokenParser.parse(token)
78-
found_attribute, key_to_replace, replace_with = None, None, None
79-
80-
attribute_level_map = {
81-
TARGET_ATTRIBUTE_LEVEL: parsed_token.attribute_value,
82-
PERSON_ATTRIBUTE_LEVEL: parsed_token.attribute_name,
83-
}
84-
85-
key_to_find = attribute_level_map.get(parsed_token.attribute_level)
86-
87-
if (
88-
parsed_token.attribute_level == TARGET_ATTRIBUTE_LEVEL
89-
and parsed_token.attribute_name in ALLOWED_CONDITIONS.__args__
90-
and parsed_token.attribute_value in ALLOWED_TARGET_ATTRIBUTES
91-
and parsed_token.attribute_name not in present_attributes
92-
):
93-
replace_with = ""
94-
95-
if replace_with != "":
96-
for attribute in person.data:
97-
is_person_attribute = attribute.get("ATTRIBUTE_TYPE") == PERSON_ATTRIBUTE_LEVEL
98-
is_allowed_target = parsed_token.attribute_name.upper() in ALLOWED_CONDITIONS.__args__
99-
is_correct_target = parsed_token.attribute_name.upper() == attribute.get("ATTRIBUTE_TYPE")
100-
101-
if ((is_allowed_target and is_correct_target) or is_person_attribute) and key_to_find in attribute:
102-
found_attribute = attribute
103-
key_to_replace = key_to_find
104-
break
105-
106-
if not found_attribute or key_to_replace is None:
107-
TokenProcessor.handle_token_not_found(parsed_token, token)
108-
109-
replace_with = TokenProcessor.apply_formatting(found_attribute, key_to_replace, parsed_token.format)
110-
text = text.replace(token, str(replace_with))
77+
replacement = TokenProcessor.get_token_replacement(token, person.data, present_attributes)
78+
text = text.replace(token, str(replacement))
11179
return text
11280

81+
@staticmethod
82+
def get_token_replacement(token: str, person_data: list[dict], present_attributes: set) -> str:
83+
parsed_token = TokenParser.parse(token)
84+
85+
if TokenProcessor.should_replace_with_empty(parsed_token, present_attributes):
86+
return ""
87+
88+
found_attribute, key_to_replace = TokenProcessor.find_matching_attribute(parsed_token, person_data)
89+
90+
if not found_attribute or not key_to_replace:
91+
TokenProcessor.handle_token_not_found(parsed_token, token)
92+
93+
return TokenProcessor.apply_formatting(found_attribute, key_to_replace, parsed_token.format)
94+
95+
@staticmethod
96+
def should_replace_with_empty(parsed_token: ParsedToken, present_attributes: set) -> bool:
97+
is_target_level = parsed_token.attribute_level == TARGET_ATTRIBUTE_LEVEL
98+
is_allowed_condition = parsed_token.attribute_name in ALLOWED_CONDITIONS.__args__
99+
is_allowed_target_attr = parsed_token.attribute_value in ALLOWED_TARGET_ATTRIBUTES
100+
is_attr_not_present = parsed_token.attribute_name not in present_attributes
101+
102+
return all([is_target_level, is_allowed_condition, is_allowed_target_attr, is_attr_not_present])
103+
104+
@staticmethod
105+
def find_matching_attribute(parsed_token: ParsedToken, person_data: list[dict]) -> tuple[dict | None, str | None]:
106+
attribute_level_map = {
107+
TARGET_ATTRIBUTE_LEVEL: parsed_token.attribute_value,
108+
PERSON_ATTRIBUTE_LEVEL: parsed_token.attribute_name,
109+
}
110+
key_to_find = attribute_level_map.get(parsed_token.attribute_level)
111+
112+
for attribute in person_data:
113+
if TokenProcessor.attribute_match(attribute, parsed_token, key_to_find):
114+
return attribute, key_to_find
115+
116+
return None, None
117+
118+
@staticmethod
119+
def attribute_match(attribute: dict, parsed_token: ParsedToken, key_to_find: str | None) -> bool:
120+
if not key_to_find or key_to_find not in attribute:
121+
return False
122+
123+
is_person_attribute = attribute.get("ATTRIBUTE_TYPE") == PERSON_ATTRIBUTE_LEVEL
124+
if is_person_attribute:
125+
return True
126+
127+
is_allowed_target = parsed_token.attribute_name.upper() in ALLOWED_CONDITIONS.__args__
128+
is_correct_target = parsed_token.attribute_name.upper() == attribute.get("ATTRIBUTE_TYPE")
129+
130+
return is_allowed_target and is_correct_target
131+
113132
@staticmethod
114133
def handle_token_not_found(parsed_token: ParsedToken, token: str) -> Never:
115134
if parsed_token.attribute_level == TARGET_ATTRIBUTE_LEVEL:

0 commit comments

Comments
 (0)