Skip to content

Commit f5a52ca

Browse files
test case - check best status is picked from the iterations
1 parent 769989b commit f5a52ca

4 files changed

Lines changed: 141 additions & 9 deletions

File tree

src/eligibility_signposting_api/common/request_validator.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@
77
from flask.typing import ResponseReturnValue
88

99
from eligibility_signposting_api.common.api_error_response import (
10+
CONSUMER_ID_NOT_PROVIDED_ERROR,
1011
INVALID_CATEGORY_ERROR,
1112
INVALID_CONDITION_FORMAT_ERROR,
1213
INVALID_INCLUDE_ACTIONS_ERROR,
13-
NHS_NUMBER_ERROR, CONSUMER_ID_NOT_PROVIDED_ERROR,
14+
NHS_NUMBER_ERROR,
1415
)
15-
from eligibility_signposting_api.config.constants import NHS_NUMBER_HEADER, CONSUMER_ID
16+
from eligibility_signposting_api.config.constants import CONSUMER_ID, NHS_NUMBER_HEADER
1617

1718
logger = logging.getLogger(__name__)
1819

@@ -50,7 +51,6 @@ def validate_request_params() -> Callable:
5051
def decorator(func: Callable) -> Callable:
5152
@wraps(func)
5253
def wrapper(*args, **kwargs) -> ResponseReturnValue: # noqa:ANN002,ANN003
53-
5454
consumer_id = request.headers.get(CONSUMER_ID)
5555
if not consumer_id:
5656
message = "You are not authorised to request"

tests/integration/conftest.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -660,6 +660,10 @@ def rules_bucket(s3_client: BaseClient) -> Generator[BucketName]:
660660
bucket_name = BucketName(os.getenv("RULES_BUCKET_NAME", "test-rules-bucket"))
661661
s3_client.create_bucket(Bucket=bucket_name, CreateBucketConfiguration={"LocationConstraint": AWS_REGION})
662662
yield bucket_name
663+
response = s3_client.list_objects_v2(Bucket=bucket_name)
664+
if "Contents" in response:
665+
objects_to_delete = [{"Key": obj["Key"]} for obj in response["Contents"]]
666+
s3_client.delete_objects(Bucket=bucket_name, Delete={"Objects": objects_to_delete})
663667
s3_client.delete_bucket(Bucket=bucket_name)
664668

665669

@@ -668,6 +672,10 @@ def consumer_mapping_bucket(s3_client: BaseClient) -> Generator[BucketName]:
668672
bucket_name = BucketName(os.getenv("CONSUMER_MAPPING_BUCKET_NAME", "test-consumer-mapping-bucket"))
669673
s3_client.create_bucket(Bucket=bucket_name, CreateBucketConfiguration={"LocationConstraint": AWS_REGION})
670674
yield bucket_name
675+
response = s3_client.list_objects_v2(Bucket=bucket_name)
676+
if "Contents" in response:
677+
objects_to_delete = [{"Key": obj["Key"]} for obj in response["Contents"]]
678+
s3_client.delete_objects(Bucket=bucket_name, Delete={"Objects": objects_to_delete})
671679
s3_client.delete_bucket(Bucket=bucket_name)
672680

673681

tests/integration/in_process/test_eligibility_endpoint.py

Lines changed: 127 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,13 @@
1717
)
1818

1919
from eligibility_signposting_api.config.constants import CONSUMER_ID
20-
from eligibility_signposting_api.model.campaign_config import CampaignConfig
20+
from eligibility_signposting_api.model.campaign_config import CampaignConfig, RuleComparator
2121
from eligibility_signposting_api.model.consumer_mapping import ConsumerId, ConsumerMapping
2222
from eligibility_signposting_api.model.eligibility_status import (
2323
NHSNumber,
2424
)
2525
from eligibility_signposting_api.repos.campaign_repo import BucketName
26+
from tests.fixtures.builders.model import rule
2627

2728

2829
class TestBaseLine:
@@ -1161,7 +1162,7 @@ def test_valid_response_when_consumer_has_a_valid_campaign_config_mapping( # no
11611162
@pytest.mark.parametrize(
11621163
("consumer_id", "expected_campaign_id"),
11631164
[
1164-
#Consumer requesting for ALL
1165+
# Consumer requesting for ALL
11651166
# Consumer is mapped only to RSV_campaign_id_1
11661167
("consumer-id-1", "RSV_campaign_id_1"),
11671168
# Consumer is mapped only to RSV_campaign_id_2
@@ -1178,6 +1179,7 @@ def test_valid_response_when_consumer_has_a_valid_campaign_config_mapping( # no
11781179
)
11791180
@pytest.mark.parametrize(
11801181
("campaign_configs", "consumer_mappings", "requested_conditions", "requested_category"),
1182+
# consumer mappings and campaign configs are static here
11811183
[
11821184
(
11831185
[
@@ -1204,7 +1206,7 @@ def test_valid_response_when_consumer_has_a_valid_campaign_config_mapping( # no
12041206
],
12051207
indirect=["campaign_configs", "consumer_mappings"],
12061208
)
1207-
def test_if_correct_campaign_is_chosen_for_the_consumer_if_there_exists_multiple_campaign_per_target( # noqa : PLR0913
1209+
def test_if_correct_campaign_is_chosen_for_the_consumer_when_multiple_campaign_exists_per_target_giving_same_status( # noqa : PLR0913
12081210
self,
12091211
client: FlaskClient,
12101212
persisted_person: NHSNumber,
@@ -1238,3 +1240,125 @@ def test_if_correct_campaign_is_chosen_for_the_consumer_if_there_exists_multiple
12381240
assert_that(audit_data["response"]["condition"][0].get("campaignId"), equal_to(expected_campaign_id))
12391241
else:
12401242
assert_that(len(audit_data["response"]["condition"]), equal_to(0))
1243+
1244+
def test_if_campaign_having_best_status_is_chosen_if_there_exists_multiple_campaign_per_target( # noqa : PLR0913
1245+
self,
1246+
client: FlaskClient,
1247+
persisted_person_pc_sw19: NHSNumber,
1248+
s3_client: BaseClient,
1249+
consumer_mapping_bucket: BucketName,
1250+
rules_bucket: BucketName,
1251+
secretsmanager_client: BaseClient, # noqa: ARG002
1252+
):
1253+
# Given
1254+
consumer_id = "consumer-n3bs-jo4hn-ce4na"
1255+
headers = {"nhs-login-nhs-number": str(persisted_person_pc_sw19), CONSUMER_ID: consumer_id}
1256+
1257+
# Consumer Mapping Data
1258+
s3_client.put_object(
1259+
Bucket=consumer_mapping_bucket,
1260+
Key="consumer_mapping.json",
1261+
Body=json.dumps(
1262+
{
1263+
consumer_id: [
1264+
{"Campaign": "RSV_campaign_id_not_actionable"},
1265+
{"Campaign": "RSV_campaign_id_actionable"},
1266+
],
1267+
}
1268+
),
1269+
ContentType="application/json",
1270+
)
1271+
1272+
# Campaign configs
1273+
campaign_1 = rule.CampaignConfigFactory.build(
1274+
id="RSV_campaign_id_not_actionable",
1275+
target="RSV",
1276+
type="V",
1277+
iterations=[
1278+
rule.IterationFactory.build(
1279+
iteration_rules=[
1280+
rule.PostcodeSuppressionRuleFactory.build(name="Exclude SW19", description=""),
1281+
],
1282+
iteration_cohorts=[
1283+
rule.IterationCohortFactory.build(
1284+
cohort_label="cohort1",
1285+
cohort_group="cohort_group1",
1286+
positive_description="positive_description",
1287+
)
1288+
],
1289+
status_text=None,
1290+
)
1291+
],
1292+
)
1293+
1294+
campaign_2 = rule.CampaignConfigFactory.build(
1295+
id="RSV_campaign_id_actionable",
1296+
target="RSV",
1297+
type="V",
1298+
iterations=[
1299+
rule.IterationFactory.build(
1300+
iteration_rules=[
1301+
rule.PostcodeSuppressionRuleFactory.build(name="Exclude M4", comparator=RuleComparator("M4")),
1302+
],
1303+
iteration_cohorts=[
1304+
rule.IterationCohortFactory.build(
1305+
cohort_label="cohort1",
1306+
cohort_group="cohort_group1",
1307+
positive_description="positive_description",
1308+
)
1309+
],
1310+
status_text=None,
1311+
)
1312+
],
1313+
)
1314+
1315+
for campaign in [campaign_1, campaign_2]:
1316+
s3_client.put_object(
1317+
Bucket=rules_bucket,
1318+
Key=f"{campaign.id}.json",
1319+
Body=json.dumps({"CampaignConfig": campaign.model_dump(by_alias=True)}),
1320+
ContentType="application/json",
1321+
)
1322+
1323+
# When
1324+
response = client.get(f"/patient-check/{persisted_person_pc_sw19}?includeActions=Y", headers=headers)
1325+
1326+
# Then
1327+
assert_that(
1328+
response,
1329+
is_response()
1330+
.with_status_code(HTTPStatus.OK)
1331+
.and_text(
1332+
is_json_that(
1333+
has_entry(
1334+
"processedSuggestions",
1335+
equal_to(
1336+
[
1337+
{
1338+
"condition": "RSV",
1339+
"status": "Actionable",
1340+
"eligibilityCohorts": [
1341+
{
1342+
"cohortCode": "cohort_group1",
1343+
"cohortStatus": "Actionable",
1344+
"cohortText": "positive_description",
1345+
}
1346+
],
1347+
"actions": [
1348+
{
1349+
"actionCode": "action_code",
1350+
"actionType": "defaultcomms",
1351+
"description": "",
1352+
"urlLabel": "",
1353+
"urlLink": "",
1354+
}
1355+
],
1356+
"suitabilityRules": [],
1357+
"statusText": "You should have the RSV vaccine",
1358+
}
1359+
]
1360+
),
1361+
)
1362+
)
1363+
),
1364+
)

tests/unit/common/test_request_validator.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ class TestValidateRequestParams:
4242
@pytest.mark.parametrize(
4343
"headers",
4444
[
45-
{}, # header missing entirely - request from application restricted consumer
45+
{}, # nhs header missing entirely - request from application restricted consumer
4646
{"nhs-login-nhs-number": "1234567890"}, # valid request from consumer
4747
],
4848
)
@@ -54,7 +54,7 @@ def test_validate_request_params_success(self, headers, app, caplog):
5454

5555
with app.test_request_context(
5656
"/dummy?id=1234567890",
57-
headers=headers,
57+
headers={"consumer-id": "some-consumer"} | headers,
5858
method="GET",
5959
):
6060
with caplog.at_level(logging.INFO):
@@ -80,7 +80,7 @@ def test_validate_request_params_nhs_mismatch(self, headers, app, caplog):
8080

8181
with app.test_request_context(
8282
"/dummy?id=1234567890",
83-
headers=headers,
83+
headers={"consumer-id": "some-id"} | headers,
8484
method="GET",
8585
):
8686
with caplog.at_level(logging.INFO):

0 commit comments

Comments
 (0)