Skip to content

Commit fa80df6

Browse files
consumer config structure modification
1 parent f525d01 commit fa80df6

7 files changed

Lines changed: 206 additions & 143 deletions

File tree

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
from typing import NewType
22

3-
from pydantic import RootModel
3+
from pydantic import BaseModel, RootModel
44

55
from eligibility_signposting_api.model.campaign_config import CampaignID
66

77
ConsumerId = NewType("ConsumerId", str)
88

99

10-
class ConsumerMapping(RootModel[dict[ConsumerId, list[CampaignID]]]):
11-
def get(self, key: ConsumerId, default: list[CampaignID] | None = None) -> list[CampaignID] | None:
10+
class ConsumerCampaign(BaseModel):
11+
campaign: CampaignID
12+
description: str | None = None
13+
14+
15+
class ConsumerMapping(RootModel[dict[ConsumerId, list[ConsumerCampaign]]]):
16+
def get(self, key: ConsumerId, default: list[ConsumerCampaign] | None = None) -> list[ConsumerCampaign] | None:
1217
return self.root.get(key, default)

src/eligibility_signposting_api/repos/consumer_mapping_repo.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,18 @@ def __init__(
2626
self.bucket_name = bucket_name
2727

2828
def get_permitted_campaign_ids(self, consumer_id: ConsumerId) -> list[CampaignID] | None:
29-
consumer_mappings = self.s3_client.list_objects(Bucket=self.bucket_name)["Contents"][0]
30-
response = self.s3_client.get_object(Bucket=self.bucket_name, Key=f"{consumer_mappings['Key']}")
29+
objects = self.s3_client.list_objects(Bucket=self.bucket_name).get("Contents")
30+
31+
if not objects:
32+
return None
33+
34+
consumer_mappings_obj = objects[0]
35+
response = self.s3_client.get_object(Bucket=self.bucket_name, Key=consumer_mappings_obj["Key"])
3136
body = response["Body"].read()
32-
return ConsumerMapping.model_validate(json.loads(body)).get(consumer_id)
37+
38+
mapping_result = ConsumerMapping.model_validate(json.loads(body)).get(consumer_id)
39+
40+
if mapping_result is None:
41+
return None
42+
43+
return [item.campaign for item in mapping_result]

tests/integration/conftest.py

Lines changed: 59 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
StartDate,
3232
StatusText,
3333
)
34-
from eligibility_signposting_api.model.consumer_mapping import ConsumerId, ConsumerMapping
34+
from eligibility_signposting_api.model.consumer_mapping import ConsumerCampaign, ConsumerId, ConsumerMapping
3535
from eligibility_signposting_api.processors.hashing_service import HashingService, HashSecretName
3636
from eligibility_signposting_api.repos import SecretRepo
3737
from eligibility_signposting_api.repos.campaign_repo import BucketName
@@ -1114,7 +1114,7 @@ def campaign_config_with_missing_descriptions_missing_rule_text(
11141114
@pytest.fixture
11151115
def campaign_configs(request, s3_client: BaseClient, rules_bucket: BucketName) -> Generator[list[CampaignConfig]]:
11161116
"""Create and upload multiple campaign configs to S3, then clean up after tests."""
1117-
campaigns, campaign_data_keys = [], []
1117+
campaigns, campaign_data_keys = [], [] # noqa: F841
11181118

11191119
raw = getattr(
11201120
request, "param", [("RSV", "RSV_campaign_id"), ("COVID", "COVID_campaign_id"), ("FLU", "FLU_campaign_id")]
@@ -1167,179 +1167,146 @@ def consumer_id() -> ConsumerId:
11671167
return ConsumerId("23-mic7heal-jor6don")
11681168

11691169

1170-
@pytest.fixture(scope="class")
1171-
def consumer_mapping_with_campaign_config_with_invalid_tokens(
1172-
s3_client: BaseClient,
1173-
consumer_mapping_bucket: BucketName,
1174-
campaign_config_with_invalid_tokens: CampaignConfig,
1175-
consumer_id: ConsumerId,
1176-
) -> Generator[ConsumerMapping]:
1170+
def create_and_put_consumer_mapping_in_s3(
1171+
campaign_config: CampaignConfig, consumer_id: str, consumer_mapping_bucket, s3_client
1172+
) -> ConsumerMapping:
11771173
consumer_mapping = ConsumerMapping.model_validate({})
1178-
consumer_mapping.root[ConsumerId(consumer_id)] = [campaign_config_with_invalid_tokens.id]
1174+
campaign_entry = ConsumerCampaign(campaign=campaign_config.id, description="Test description for campaign mapping")
11791175

1176+
consumer_mapping.root[ConsumerId(consumer_id)] = [campaign_entry]
11801177
consumer_mapping_data = consumer_mapping.model_dump(by_alias=True)
11811178
s3_client.put_object(
11821179
Bucket=consumer_mapping_bucket,
11831180
Key="consumer_mapping.json",
11841181
Body=json.dumps(consumer_mapping_data),
11851182
ContentType="application/json",
11861183
)
1184+
return consumer_mapping
1185+
1186+
1187+
@pytest.fixture(scope="class")
1188+
def consumer_mapped_to_campaign_having_invalid_tokens(
1189+
s3_client: BaseClient,
1190+
consumer_mapping_bucket: BucketName,
1191+
campaign_config_with_invalid_tokens: CampaignConfig,
1192+
consumer_id: ConsumerId,
1193+
) -> Generator[ConsumerMapping]:
1194+
consumer_mapping = create_and_put_consumer_mapping_in_s3(
1195+
campaign_config_with_invalid_tokens, consumer_id, consumer_mapping_bucket, s3_client
1196+
)
11871197
yield consumer_mapping
11881198
s3_client.delete_object(Bucket=consumer_mapping_bucket, Key="consumer_mapping.json")
11891199

11901200

11911201
@pytest.fixture(scope="class")
1192-
def consumer_mapping_with_campaign_config_with_tokens(
1202+
def consumer_mapped_to_campaign_having_tokens(
11931203
s3_client: BaseClient,
11941204
consumer_mapping_bucket: BucketName,
11951205
campaign_config_with_tokens: CampaignConfig,
11961206
consumer_id: ConsumerId,
11971207
) -> Generator[ConsumerMapping]:
1198-
consumer_mapping = ConsumerMapping.model_validate({})
1199-
consumer_mapping.root[ConsumerId(consumer_id)] = [campaign_config_with_tokens.id]
1200-
1201-
consumer_mapping_data = consumer_mapping.model_dump(by_alias=True)
1202-
s3_client.put_object(
1203-
Bucket=consumer_mapping_bucket,
1204-
Key="consumer_mapping.json",
1205-
Body=json.dumps(consumer_mapping_data),
1206-
ContentType="application/json",
1208+
consumer_mapping = create_and_put_consumer_mapping_in_s3(
1209+
campaign_config_with_tokens, consumer_id, consumer_mapping_bucket, s3_client
12071210
)
12081211
yield consumer_mapping
12091212
s3_client.delete_object(Bucket=consumer_mapping_bucket, Key="consumer_mapping.json")
12101213

12111214

12121215
@pytest.fixture(scope="class")
1213-
def consumer_mapping_with_rsv(
1216+
def consumer_mapped_to_rsv_campaign(
12141217
s3_client: BaseClient,
12151218
consumer_mapping_bucket: BucketName,
12161219
rsv_campaign_config: CampaignConfig,
12171220
consumer_id: ConsumerId,
12181221
) -> Generator[ConsumerMapping]:
1219-
consumer_mapping = ConsumerMapping.model_validate({})
1220-
consumer_mapping.root[ConsumerId(consumer_id)] = [rsv_campaign_config.id]
1221-
1222-
consumer_mapping_data = consumer_mapping.model_dump(by_alias=True)
1223-
s3_client.put_object(
1224-
Bucket=consumer_mapping_bucket,
1225-
Key="consumer_mapping.json",
1226-
Body=json.dumps(consumer_mapping_data),
1227-
ContentType="application/json",
1222+
consumer_mapping = create_and_put_consumer_mapping_in_s3(
1223+
rsv_campaign_config, consumer_id, consumer_mapping_bucket, s3_client
12281224
)
12291225
yield consumer_mapping
12301226
s3_client.delete_object(Bucket=consumer_mapping_bucket, Key="consumer_mapping.json")
12311227

12321228

12331229
@pytest.fixture(scope="class")
1234-
def consumer_mapping_with_campaign_config_with_and_rule(
1230+
def consumer_mapped_to_campaign_having_and_rule(
12351231
s3_client: BaseClient,
12361232
consumer_mapping_bucket: BucketName,
12371233
campaign_config_with_and_rule: CampaignConfig,
12381234
consumer_id: ConsumerId,
12391235
) -> Generator[ConsumerMapping]:
1240-
consumer_mapping = ConsumerMapping.model_validate({})
1241-
consumer_mapping.root[ConsumerId(consumer_id)] = [campaign_config_with_and_rule.id]
1242-
1243-
consumer_mapping_data = consumer_mapping.model_dump(by_alias=True)
1244-
s3_client.put_object(
1245-
Bucket=consumer_mapping_bucket,
1246-
Key="consumer_mapping.json",
1247-
Body=json.dumps(consumer_mapping_data),
1248-
ContentType="application/json",
1236+
consumer_mapping = create_and_put_consumer_mapping_in_s3(
1237+
campaign_config_with_and_rule, consumer_id, consumer_mapping_bucket, s3_client
12491238
)
12501239
yield consumer_mapping
12511240
s3_client.delete_object(Bucket=consumer_mapping_bucket, Key="consumer_mapping.json")
12521241

12531242

12541243
@pytest.fixture
1255-
def consumer_mapping_with_campaign_config_with_missing_descriptions_missing_rule_text(
1244+
def consumer_mapped_to_campaign_missing_descriptions_and_rule_text(
12561245
s3_client: BaseClient,
12571246
consumer_mapping_bucket: ConsumerMapping,
12581247
campaign_config_with_missing_descriptions_missing_rule_text: CampaignConfig,
12591248
consumer_id: ConsumerId,
12601249
):
1261-
mapping = ConsumerMapping.model_validate({})
1262-
mapping.root[consumer_id] = [campaign_config_with_missing_descriptions_missing_rule_text.id]
1263-
1264-
s3_client.put_object(
1265-
Bucket=consumer_mapping_bucket,
1266-
Key="consumer_mapping.json",
1267-
Body=json.dumps(mapping.model_dump(by_alias=True)),
1268-
ContentType="application/json",
1250+
consumer_mapping = create_and_put_consumer_mapping_in_s3(
1251+
campaign_config_with_missing_descriptions_missing_rule_text, consumer_id, consumer_mapping_bucket, s3_client
12691252
)
1270-
yield mapping
1253+
yield consumer_mapping
12711254
s3_client.delete_object(Bucket=consumer_mapping_bucket, Key="consumer_mapping.json")
12721255

12731256

12741257
@pytest.fixture
1275-
def consumer_mapping_with_campaign_config_with_rules_having_rule_code(
1258+
def consumer_mapped_to_campaign_having_rules_with_rule_code(
12761259
s3_client: BaseClient,
12771260
consumer_mapping_bucket: ConsumerMapping,
12781261
campaign_config_with_rules_having_rule_code: CampaignConfig,
12791262
consumer_id: ConsumerId,
12801263
):
1281-
mapping = ConsumerMapping.model_validate({})
1282-
mapping.root[consumer_id] = [campaign_config_with_rules_having_rule_code.id]
1283-
1284-
s3_client.put_object(
1285-
Bucket=consumer_mapping_bucket,
1286-
Key="consumer_mapping.json",
1287-
Body=json.dumps(mapping.model_dump(by_alias=True)),
1288-
ContentType="application/json",
1264+
consumer_mapping = create_and_put_consumer_mapping_in_s3(
1265+
campaign_config_with_rules_having_rule_code, consumer_id, consumer_mapping_bucket, s3_client
12891266
)
1290-
yield mapping
1267+
yield consumer_mapping
12911268
s3_client.delete_object(Bucket=consumer_mapping_bucket, Key="consumer_mapping.json")
12921269

12931270

12941271
@pytest.fixture
1295-
def consumer_mapping_with_campaign_config_with_rules_having_rule_mapper(
1272+
def consumer_mapped_to_campaign_having_rules_with_rule_mapper(
12961273
s3_client: BaseClient,
12971274
consumer_mapping_bucket: ConsumerMapping,
12981275
campaign_config_with_rules_having_rule_mapper: CampaignConfig,
12991276
consumer_id: ConsumerId,
13001277
):
1301-
mapping = ConsumerMapping.model_validate({})
1302-
mapping.root[consumer_id] = [campaign_config_with_rules_having_rule_mapper.id]
1303-
1304-
s3_client.put_object(
1305-
Bucket=consumer_mapping_bucket,
1306-
Key="consumer_mapping.json",
1307-
Body=json.dumps(mapping.model_dump(by_alias=True)),
1308-
ContentType="application/json",
1278+
consumer_mapping = create_and_put_consumer_mapping_in_s3(
1279+
campaign_config_with_rules_having_rule_mapper, consumer_id, consumer_mapping_bucket, s3_client
13091280
)
1310-
yield mapping
1281+
yield consumer_mapping
13111282
s3_client.delete_object(Bucket=consumer_mapping_bucket, Key="consumer_mapping.json")
13121283

13131284

13141285
@pytest.fixture
1315-
def consumer_mapping_with_only_virtual_cohort(
1286+
def consumer_mapped_to_campaign_having_only_virtual_cohort(
13161287
s3_client: BaseClient,
13171288
consumer_mapping_bucket: ConsumerMapping,
13181289
campaign_config_with_virtual_cohort: CampaignConfig,
13191290
consumer_id: ConsumerId,
13201291
):
1321-
mapping = ConsumerMapping.model_validate({})
1322-
mapping.root[consumer_id] = [campaign_config_with_virtual_cohort.id]
1323-
1324-
s3_client.put_object(
1325-
Bucket=consumer_mapping_bucket,
1326-
Key="consumer_mapping.json",
1327-
Body=json.dumps(mapping.model_dump(by_alias=True)),
1328-
ContentType="application/json",
1292+
consumer_mapping = create_and_put_consumer_mapping_in_s3(
1293+
campaign_config_with_virtual_cohort, consumer_id, consumer_mapping_bucket, s3_client
13291294
)
1330-
yield mapping
1295+
yield consumer_mapping
13311296
s3_client.delete_object(Bucket=consumer_mapping_bucket, Key="consumer_mapping.json")
13321297

13331298

13341299
@pytest.fixture
1335-
def consumer_mapping_with_inactive_iteration_config(
1300+
def consumer_mapped_to_campaign_having_inactive_iteration_config(
13361301
s3_client: BaseClient,
13371302
consumer_mapping_bucket: ConsumerMapping,
13381303
inactive_iteration_config: list[CampaignConfig],
13391304
consumer_id: ConsumerId,
13401305
):
13411306
mapping = ConsumerMapping.model_validate({})
1342-
mapping.root[consumer_id] = [cc.id for cc in inactive_iteration_config]
1307+
mapping.root[consumer_id] = [
1308+
ConsumerCampaign(campaign=cc.id, description=f"Description for {cc.id}") for cc in inactive_iteration_config
1309+
]
13431310

13441311
s3_client.put_object(
13451312
Bucket=consumer_mapping_bucket,
@@ -1352,14 +1319,16 @@ def consumer_mapping_with_inactive_iteration_config(
13521319

13531320

13541321
@pytest.fixture(scope="class")
1355-
def consumer_mapping_with_multiple_campaign_configs(
1322+
def consumer_mapped_to_multiple_campaign_configs(
13561323
multiple_campaign_configs: list[CampaignConfig],
13571324
consumer_id: ConsumerId,
13581325
s3_client: BaseClient,
13591326
consumer_mapping_bucket: BucketName,
13601327
) -> Generator[ConsumerMapping]:
13611328
mapping = ConsumerMapping.model_validate({})
1362-
mapping.root[consumer_id] = [cc.id for cc in multiple_campaign_configs]
1329+
mapping.root[consumer_id] = [
1330+
ConsumerCampaign(campaign=cc.id, description=f"Description for {cc.id}") for cc in multiple_campaign_configs
1331+
]
13631332

13641333
s3_client.put_object(
13651334
Bucket=consumer_mapping_bucket,
@@ -1388,15 +1357,16 @@ def consumer_mappings(
13881357

13891358

13901359
@pytest.fixture(scope="class")
1391-
def consumer_mapping_with_various_targets(
1360+
def consumer_mapped_to_with_various_targets(
13921361
s3_client: BaseClient, consumer_mapping_bucket: BucketName
13931362
) -> Generator[ConsumerMapping]:
13941363
consumer_mapping = ConsumerMapping.model_validate({})
1364+
13951365
consumer_mapping.root[ConsumerId("23-mic7heal-jor6don")] = [
1396-
CampaignID("campaign_start_date"),
1397-
CampaignID("campaign_start_date_plus_one_day"),
1398-
CampaignID("campaign_today"),
1399-
CampaignID("campaign_tomorrow"),
1366+
ConsumerCampaign(campaign=CampaignID("campaign_start_date")),
1367+
ConsumerCampaign(campaign=CampaignID("campaign_start_date_plus_one_day")),
1368+
ConsumerCampaign(campaign=CampaignID("campaign_today")),
1369+
ConsumerCampaign(campaign=CampaignID("campaign_tomorrow")),
14001370
]
14011371

14021372
consumer_mapping_data = consumer_mapping.model_dump(by_alias=True)

0 commit comments

Comments
 (0)