Coverage for benefits/enrollment_littlepay/models.py: 100%
35 statements
« prev ^ index » next coverage.py v7.8.2, created at 2025-06-06 20:07 +0000
« prev ^ index » next coverage.py v7.8.2, created at 2025-06-06 20:07 +0000
1from django.core.exceptions import ValidationError
2from django.db import models
4from benefits.core import context as core_context
5from benefits.core.models import SecretNameField, Environment
6from benefits.secrets import get_secret_by_name
9class LittlepayConfig(models.Model):
10 """Configuration for connecting to Littlepay, an entity that applies transit agency fare rules to rider transactions."""
12 id = models.AutoField(primary_key=True)
13 environment = models.TextField(
14 choices=Environment,
15 help_text="A label to indicate which environment this configuration is for.",
16 )
17 agency_slug = models.SlugField(
18 choices=core_context.AgencySlug,
19 help_text="A label to indicate which agency this configuration is for. Note: the field that controls which configuration an agency actually uses is on the TransitAgency model.", # noqa
20 )
21 audience = models.TextField(
22 help_text="This agency's audience value used to access the TransitProcessor's API.", default="", blank=True
23 )
24 client_id = models.TextField(
25 help_text="This agency's client_id value used to access the TransitProcessor's API.", default="", blank=True
26 )
27 client_secret_name = SecretNameField(
28 help_text="The name of the secret containing this agency's client_secret value used to access the TransitProcessor's API.", # noqa: E501
29 default="",
30 blank=True,
31 )
33 @property
34 def api_base_url(self):
35 if self.environment == Environment.QA.value:
36 return get_secret_by_name("littlepay-qa-api-base-url")
37 elif self.environment == Environment.PROD.value:
38 return get_secret_by_name("littlepay-prod-api-base-url")
39 else:
40 raise ValueError(f"Unexpected value for environment: {self.environment}")
42 @property
43 def client_secret(self):
44 secret_field = self._meta.get_field("client_secret_name")
45 return secret_field.secret_value(self)
47 def clean(self):
48 field_errors = {}
50 if hasattr(self, "transitagency") and self.transitagency.active:
51 message = "This field is required when this configuration is referenced by an active transit agency."
52 needed = dict(audience=self.audience, client_id=self.client_id, client_secret_name=self.client_secret_name)
53 field_errors.update({k: ValidationError(message) for k, v in needed.items() if not v})
55 if field_errors:
56 raise ValidationError(field_errors)
58 def __str__(self):
59 environment_label = Environment(self.environment).label if self.environment else "unknown"
60 agency_slug = self.agency_slug if self.agency_slug else "(no agency)"
61 return f"({environment_label}) {agency_slug}"