|
1 | 1 | import pytest |
2 | 2 | from pydantic import ValidationError |
3 | 3 |
|
| 4 | +from eligibility_signposting_api.model.campaign_config import RuleAttributeLevel |
4 | 5 | from rules_validation_api.validators.iteration_validator import IterationRuleValidation |
5 | 6 |
|
6 | 7 |
|
@@ -80,8 +81,18 @@ def test_invalid_priority(self, priority_value, valid_iteration_rule_with_only_m |
80 | 81 | with pytest.raises(ValidationError): |
81 | 82 | IterationRuleValidation(**data) |
82 | 83 |
|
83 | | - @pytest.mark.parametrize("attribute_level", ["PERSON", "TARGET", "COHORT"]) |
84 | | - def test_valid_attribute_level(self, attribute_level, valid_iteration_rule_with_only_mandatory_fields): |
| 84 | + @pytest.mark.parametrize("attribute_level", ["PERSON", "TARGET"]) |
| 85 | + def test_valid_attribute_level_person_and_targer( |
| 86 | + self, attribute_level, valid_iteration_rule_with_only_mandatory_fields |
| 87 | + ): |
| 88 | + data = valid_iteration_rule_with_only_mandatory_fields.copy() |
| 89 | + data["AttributeLevel"] = attribute_level |
| 90 | + data["AttributeName"] = "Something" # Ignoring the validation constraint btw AttributeLevel and AttributeName |
| 91 | + result = IterationRuleValidation(**data) |
| 92 | + assert result.attribute_level == attribute_level |
| 93 | + |
| 94 | + @pytest.mark.parametrize("attribute_level", ["COHORT"]) |
| 95 | + def test_valid_attribute_level_cohort(self, attribute_level, valid_iteration_rule_with_only_mandatory_fields): |
85 | 96 | data = valid_iteration_rule_with_only_mandatory_fields.copy() |
86 | 97 | data["AttributeLevel"] = attribute_level |
87 | 98 | data["AttributeName"] = None # Ignoring the validation constraint btw AttributeLevel and AttributeName |
@@ -148,7 +159,7 @@ def test_rule_stop_boolean_resolution( |
148 | 159 |
|
149 | 160 | class TestOptionalFieldsSchemaValidations: |
150 | 161 | # AttributeName |
151 | | - @pytest.mark.parametrize("attr_name", ["status", "user_type", None]) |
| 162 | + @pytest.mark.parametrize("attr_name", ["status", "user_type"]) |
152 | 163 | def test_valid_attribute_name(self, attr_name, valid_iteration_rule_with_only_mandatory_fields): |
153 | 164 | data = valid_iteration_rule_with_only_mandatory_fields.copy() |
154 | 165 | data["AttributeName"] = attr_name |
@@ -192,7 +203,7 @@ def test_invalid_cohort_label(self, label, valid_iteration_rule_with_only_mandat |
192 | 203 | IterationRuleValidation(**data) |
193 | 204 |
|
194 | 205 | # AttributeTarget |
195 | | - @pytest.mark.parametrize("target", ["target_value", None]) |
| 206 | + @pytest.mark.parametrize("target", ["target_value"]) |
196 | 207 | def test_valid_attribute_target(self, target, valid_iteration_rule_with_only_mandatory_fields): |
197 | 208 | data = valid_iteration_rule_with_only_mandatory_fields.copy() |
198 | 209 | data["AttributeTarget"] = target |
@@ -291,3 +302,57 @@ def test_valid_when_cohort_label_absent_for_non_f_s_types( |
291 | 302 | data.pop("CohortLabel", None) |
292 | 303 | result = IterationRuleValidation(**data) |
293 | 304 | assert result.cohort_label is None |
| 305 | + |
| 306 | + @pytest.mark.parametrize( |
| 307 | + ("attribute_level", "attribute_name", "is_valid"), |
| 308 | + [ |
| 309 | + (RuleAttributeLevel.COHORT, None, True), # Allowed: name optional for cohort |
| 310 | + (RuleAttributeLevel.COHORT, "COHORT_LABEL", True), # Allowed: name provided |
| 311 | + (RuleAttributeLevel.TARGET, "RSV", True), # Allowed: name provided for target |
| 312 | + (RuleAttributeLevel.TARGET, None, False), # NOT allowed: missing for non-cohort |
| 313 | + ], |
| 314 | + ) |
| 315 | + def test_attribute_name_optional_only_for_cohort( |
| 316 | + self, attribute_level, attribute_name, is_valid, valid_iteration_rule_with_only_mandatory_fields |
| 317 | + ): |
| 318 | + data = valid_iteration_rule_with_only_mandatory_fields.copy() |
| 319 | + data["AttributeLevel"] = attribute_level |
| 320 | + data["AttributeName"] = attribute_name |
| 321 | + |
| 322 | + if is_valid: |
| 323 | + # Should validate with no exceptions |
| 324 | + IterationRuleValidation(**data) |
| 325 | + else: |
| 326 | + with pytest.raises(ValidationError) as exc: |
| 327 | + IterationRuleValidation(**data) |
| 328 | + |
| 329 | + assert "AttributeName must be set" in str(exc.value) |
| 330 | + |
| 331 | + @pytest.mark.parametrize( |
| 332 | + ("attribute_level", "attribute_target", "attribute_name", "is_valid"), |
| 333 | + [ |
| 334 | + (RuleAttributeLevel.TARGET, "RSV", "BOOKED_APPOINTMENT_DATE", True), # Valid: required for TARGET |
| 335 | + (RuleAttributeLevel.TARGET, None, "BOOKED_APPOINTMENT_DATE", False), # Invalid: missing |
| 336 | + (RuleAttributeLevel.COHORT, None, "COHORT_LABEL", True), # Valid: not required |
| 337 | + ], |
| 338 | + ) |
| 339 | + def test_attribute_target_mandatory_for_target_level( |
| 340 | + self, |
| 341 | + attribute_level, |
| 342 | + attribute_target, |
| 343 | + attribute_name, |
| 344 | + is_valid, |
| 345 | + valid_iteration_rule_with_only_mandatory_fields, |
| 346 | + ): |
| 347 | + data = valid_iteration_rule_with_only_mandatory_fields.copy() |
| 348 | + data["AttributeLevel"] = attribute_level |
| 349 | + data["AttributeTarget"] = attribute_target |
| 350 | + data["AttributeName"] = attribute_name |
| 351 | + |
| 352 | + if is_valid: |
| 353 | + IterationRuleValidation(**data) |
| 354 | + else: |
| 355 | + with pytest.raises(ValidationError) as exc: |
| 356 | + IterationRuleValidation(**data) |
| 357 | + |
| 358 | + assert "AttributeTarget is mandatory" in str(exc.value) |
0 commit comments