99from eligibility_signposting_api .audit .audit_context import AuditContext
1010from eligibility_signposting_api .audit .audit_models import AuditAction , AuditEvent
1111from eligibility_signposting_api .audit .audit_service import AuditService
12- from eligibility_signposting_api .model .campaign_config import CampaignID , CampaignVersion , RuleType
12+ from eligibility_signposting_api .model import campaign_config
13+ from eligibility_signposting_api .model .campaign_config import CampaignID , CampaignVersion , CohortLabel , RuleType
1314from eligibility_signposting_api .model .eligibility_status import (
1415 ActionCode ,
1516 ActionDescription ,
@@ -82,7 +83,7 @@ def test_add_request_details_when_headers_are_empty_sets_audit_log_on_g(app):
8283 assert isinstance (audit_req .request_timestamp , datetime )
8384
8485
85- def test_append_audit_condition_adds_condition_to_audit_log_on_g (app ):
86+ def test_append_audit_condition_adds_condition_to_audit_log_on_g_for_actionable_status (app ):
8687 suggested_actions : list [SuggestedAction ] | None
8788 condition_name : ConditionName
8889 campaign_details : tuple [CampaignID | None , CampaignVersion | None ]
@@ -101,13 +102,27 @@ def test_append_audit_condition_adds_condition_to_audit_log_on_g(app):
101102 condition_name = ConditionName ("Condition1" )
102103 iteration = IterationFactory .build (version = 12345 )
103104 audit_rules = [
105+ Reason (
106+ rule_type = RuleType .redirect ,
107+ rule_name = RuleName ("RedirectRuleName1" ),
108+ rule_description = RuleDescription ("RedirectRuleDescription1" ),
109+ matcher_matched = True ,
110+ rule_priority = RulePriority ("1" ),
111+ ),
104112 Reason (
105113 rule_type = RuleType .filter ,
106114 rule_name = RuleName ("FilterRuleName1" ),
107115 rule_description = RuleDescription ("FilterRuleDescription1" ),
108116 matcher_matched = True ,
109117 rule_priority = RulePriority ("1" ),
110- )
118+ ),
119+ Reason (
120+ rule_type = RuleType .suppression ,
121+ rule_name = RuleName ("SuppressionRuleName1" ),
122+ rule_description = RuleDescription ("SuppressionRuleDescription1" ),
123+ matcher_matched = True ,
124+ rule_priority = RulePriority ("1" ),
125+ ),
111126 ]
112127 cohort_group_result = CohortGroupResult (
113128 status = Status .actionable ,
@@ -120,10 +135,16 @@ def test_append_audit_condition_adds_condition_to_audit_log_on_g(app):
120135 status = Status .actionable , cohort_results = [cohort_group_result ], actions = suggested_actions
121136 )
122137 campaign_details = (CampaignID ("CampaignID1" ), CampaignVersion (123 ))
123- matched_action_detail = MatchedActionDetail (RuleName ("RedirectRuleName1" ), RulePriority ("1" ), suggested_actions )
138+ matched_action_detail = MatchedActionDetail (
139+ campaign_config .RuleName ("RedirectRuleName1" ), campaign_config .RulePriority (1 ), suggested_actions
140+ )
124141
125142 best_iteration_results = BestIterationResult (
126- iteration_result , iteration , campaign_details [0 ], campaign_details [1 ], {"CohortCode1" : cohort_group_result }
143+ iteration_result ,
144+ iteration ,
145+ campaign_details [0 ],
146+ campaign_details [1 ],
147+ {CohortLabel ("CohortCode1" ): cohort_group_result },
127148 )
128149
129150 with app .app_context ():
@@ -156,7 +177,68 @@ def test_append_audit_condition_adds_condition_to_audit_log_on_g(app):
156177 assert cond .actions == expected_audit_action
157178 assert cond .action_rule .rule_priority == "1"
158179 assert cond .action_rule .rule_name == "RedirectRuleName1"
159- assert cond .suitability_rules is None
180+ assert len (cond .suitability_rules ) == 1
181+ assert cond .suitability_rules [0 ].rule_priority == "1"
182+ assert cond .suitability_rules [0 ].rule_name == "SuppressionRuleName1"
183+ assert cond .suitability_rules [0 ].rule_message == "SuppressionRuleDescription1"
184+ assert cond .filter_rules [0 ].rule_priority == "1"
185+ assert cond .filter_rules [0 ].rule_name == "FilterRuleName1"
186+ assert cond .eligibility_cohorts [0 ].cohort_code == "CohortCode1"
187+ assert cond .eligibility_cohorts [0 ].cohort_status == "actionable"
188+ assert cond .eligibility_cohort_groups [0 ].cohort_code == "CohortCode1"
189+ assert cond .eligibility_cohort_groups [0 ].cohort_status == "actionable"
190+ assert cond .eligibility_cohort_groups [0 ].cohort_text == "CohortDescription1"
191+
192+
193+ def test_should_append_audit_suppression_rules_for_actionable_status (app ):
194+ condition_name : ConditionName
195+ campaign_details : tuple [CampaignID | None , CampaignVersion | None ]
196+
197+ condition_name = ConditionName ("Condition1" )
198+ iteration = IterationFactory .build ()
199+ audit_rules = [
200+ Reason (
201+ rule_type = RuleType .suppression ,
202+ rule_name = RuleName ("SuppressionRuleName1" ),
203+ rule_description = RuleDescription ("SuppressionRuleDescription1" ),
204+ matcher_matched = True ,
205+ rule_priority = RulePriority ("1" ),
206+ )
207+ ]
208+ cohort_group_result = CohortGroupResult (
209+ status = Status .actionable ,
210+ cohort_code = "CohortCode1" ,
211+ description = "CohortDescription1" ,
212+ audit_rules = audit_rules ,
213+ reasons = audit_rules ,
214+ )
215+ iteration_result = IterationResult (status = Status .actionable , cohort_results = [cohort_group_result ], actions = [])
216+ campaign_details = (CampaignID ("CampaignID1" ), CampaignVersion (123 ))
217+
218+ best_iteration_results = BestIterationResult (
219+ iteration_result ,
220+ iteration ,
221+ campaign_details [0 ],
222+ campaign_details [1 ],
223+ {CohortLabel ("CohortCode1" ): cohort_group_result },
224+ )
225+
226+ with app .app_context ():
227+ g .audit_log = AuditEvent ()
228+
229+ AuditContext .append_audit_condition (
230+ condition_name , best_iteration_results , MatchedActionDetail (), [cohort_group_result ]
231+ )
232+
233+ assert g .audit_log .response .condition , condition_name
234+ cond = g .audit_log .response .condition [0 ]
235+ assert cond .status == "actionable"
236+ assert cond .status_text == "You should have the Condition1 vaccine"
237+ assert cond .actions is None
238+ assert cond .action_rule is None
239+ assert cond .suitability_rules [0 ].rule_priority == "1"
240+ assert cond .suitability_rules [0 ].rule_name == "SuppressionRuleName1"
241+ assert cond .suitability_rules [0 ].rule_message == "SuppressionRuleDescription1"
160242 assert cond .filter_rules is None
161243 assert cond .eligibility_cohorts [0 ].cohort_code == "CohortCode1"
162244 assert cond .eligibility_cohorts [0 ].cohort_status == "actionable"
@@ -165,6 +247,62 @@ def test_append_audit_condition_adds_condition_to_audit_log_on_g(app):
165247 assert cond .eligibility_cohort_groups [0 ].cohort_text == "CohortDescription1"
166248
167249
250+ def test_should_append_audit_filter_rules_for_not_actionable_status (app ):
251+ condition_name : ConditionName
252+ campaign_details : tuple [CampaignID | None , CampaignVersion | None ]
253+
254+ condition_name = ConditionName ("Condition1" )
255+ iteration = IterationFactory .build ()
256+ audit_rules = [
257+ Reason (
258+ rule_type = RuleType .filter ,
259+ rule_name = RuleName ("FilterRuleName1" ),
260+ rule_description = RuleDescription ("FilterRuleDescription1" ),
261+ matcher_matched = True ,
262+ rule_priority = RulePriority ("1" ),
263+ )
264+ ]
265+ cohort_group_result = CohortGroupResult (
266+ status = Status .not_actionable ,
267+ cohort_code = "CohortCode1" ,
268+ description = "CohortDescription1" ,
269+ audit_rules = audit_rules ,
270+ reasons = audit_rules ,
271+ )
272+ iteration_result = IterationResult (status = Status .not_actionable , cohort_results = [cohort_group_result ], actions = [])
273+ campaign_details = (CampaignID ("CampaignID1" ), CampaignVersion (123 ))
274+
275+ best_iteration_results = BestIterationResult (
276+ iteration_result ,
277+ iteration ,
278+ campaign_details [0 ],
279+ campaign_details [1 ],
280+ {CohortLabel ("CohortCode1" ): cohort_group_result },
281+ )
282+
283+ with app .app_context ():
284+ g .audit_log = AuditEvent ()
285+
286+ AuditContext .append_audit_condition (
287+ condition_name , best_iteration_results , MatchedActionDetail (), [cohort_group_result ]
288+ )
289+
290+ assert g .audit_log .response .condition , condition_name
291+ cond = g .audit_log .response .condition [0 ]
292+ assert cond .status == "not_actionable"
293+ assert cond .status_text == "You should have the Condition1 vaccine"
294+ assert cond .actions is None
295+ assert cond .action_rule is None
296+ assert cond .filter_rules [0 ].rule_priority == "1"
297+ assert cond .filter_rules [0 ].rule_name == "FilterRuleName1"
298+ assert cond .suitability_rules is None
299+ assert cond .eligibility_cohorts [0 ].cohort_code == "CohortCode1"
300+ assert cond .eligibility_cohorts [0 ].cohort_status == "not_actionable"
301+ assert cond .eligibility_cohort_groups [0 ].cohort_code == "CohortCode1"
302+ assert cond .eligibility_cohort_groups [0 ].cohort_status == "not_actionable"
303+ assert cond .eligibility_cohort_groups [0 ].cohort_text == "CohortDescription1"
304+
305+
168306def test_add_response_details_adds_to_audit_log_on_g (app ):
169307 response_id = uuid .uuid4 ()
170308 last_updated = datetime (2023 , 1 , 1 , 0 , 0 , tzinfo = UTC )
@@ -207,7 +345,7 @@ def test_no_duplicates_returns_same_list():
207345def test_duplicates_are_removed ():
208346 reasons = [
209347 Reason (RuleType ("F" ), RuleName ("code1" ), RulePriority ("1" ), RuleDescription ("desc1" ), matcher_matched = True ),
210- Reason (RuleType ("S " ), RuleName ("code1 " ), RulePriority ("2 " ), RuleDescription ("desc2" ), matcher_matched = False ),
348+ Reason (RuleType ("F " ), RuleName ("code2 " ), RulePriority ("1 " ), RuleDescription ("desc2" ), matcher_matched = False ),
211349 Reason (RuleType ("R" ), RuleName ("code3" ), RulePriority ("3" ), RuleDescription ("desc3" ), matcher_matched = True ),
212350 ]
213351 expected = [
@@ -221,16 +359,3 @@ def test_empty_list_returns_empty_list():
221359 reasons = []
222360 expected = []
223361 assert AuditContext .deduplicate_reasons (reasons ) == expected
224-
225-
226- def test_reasons_with_no_description_are_filtered_out ():
227- reasons = [
228- Reason (RuleType ("F" ), RuleName ("code1" ), RulePriority ("1" ), RuleDescription ("desc1" ), matcher_matched = True ),
229- Reason (RuleType ("S" ), RuleName ("code2" ), RulePriority ("2" ), None , matcher_matched = False ),
230- Reason (RuleType ("R" ), RuleName ("code3" ), RulePriority ("3" ), RuleDescription ("desc3" ), matcher_matched = True ),
231- ]
232- expected = [
233- Reason (RuleType ("F" ), RuleName ("code1" ), RulePriority ("1" ), RuleDescription ("desc1" ), matcher_matched = True ),
234- Reason (RuleType ("R" ), RuleName ("code3" ), RulePriority ("3" ), RuleDescription ("desc3" ), matcher_matched = True ),
235- ]
236- assert AuditContext .deduplicate_reasons (reasons ) == expected
0 commit comments