Skip to content

Commit

Permalink
Merge pull request #2618 from bcgov/chore/431-allocation-tests
Browse files Browse the repository at this point in the history
Chore/431 allocation tests
  • Loading branch information
acatchpole authored Jan 3, 2025
2 parents 88aacaa + b9abee9 commit 91f80e9
Show file tree
Hide file tree
Showing 9 changed files with 1,346 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ class Migration(migrations.Migration):
(
'allocation_methodology',
models.CharField(
db_comment='The methodology used to calculate the allocated emissions', max_length=255
choices=[('Calculator', 'Calculator'), ('other', 'Other')],
default='Calculator',
db_comment='The methodology used to calculate the allocated emissions',
max_length=255,
),
),
(
Expand Down Expand Up @@ -116,6 +119,7 @@ class Migration(migrations.Migration):
constraint=models.UniqueConstraint(
fields=('report_version', 'facility_report', 'report_product', 'emission_category'),
name='unique_report_product_emission_allocation',
violation_error_message="A FacilityReport can only have one ReportProductEmissionAllocation per Report Product and Emission Category",
),
),
migrations.AddConstraint(
Expand All @@ -127,7 +131,7 @@ class Migration(migrations.Migration):
_negated=True,
),
name='allocation_other_methodology_must_have_description',
violation_error_message="A value for allocation_other_methodology_description should be provided if the allocation_methodology is 'other'",
violation_error_message="A value for allocation_other_methodology_description must be provided if the allocation_methodology is 'other'",
),
),
]
10 changes: 9 additions & 1 deletion bc_obps/reporting/models/report_product_emission_allocation.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ class ReportProductEmissionAllocation(TimeStampedModel):
A model to store the allocated ammount of emissions for a given product
"""

class AllocationMethodologyChoices(models.TextChoices):
CALCULATOR = ("Calculator",)
OTHER = "other"

report_version = models.ForeignKey(
report_version.ReportVersion,
on_delete=models.PROTECT,
Expand Down Expand Up @@ -43,6 +47,8 @@ class ReportProductEmissionAllocation(TimeStampedModel):
)
allocation_methodology = models.CharField(
max_length=255,
choices=AllocationMethodologyChoices.choices,
default=AllocationMethodologyChoices.CALCULATOR,
db_comment="The methodology used to calculate the allocated emissions",
)
allocation_other_methodology_description = models.TextField(
Expand All @@ -54,14 +60,16 @@ class ReportProductEmissionAllocation(TimeStampedModel):
class Meta:
db_table = 'erc"."report_product_emission_allocation'
db_table_comment = "A table to store the allocated amount of emissions for a given product"
app_label = 'reporting'
constraints = [
models.UniqueConstraint(
fields=["report_version", "facility_report", "report_product", "emission_category"],
name="unique_report_product_emission_allocation",
violation_error_message="A FacilityReport can only have one ReportProductEmissionAllocation per Report Product and Emission Category",
),
models.CheckConstraint(
name="allocation_other_methodology_must_have_description",
check=~Q(allocation_methodology="other", allocation_other_methodology_description__isnull=True),
violation_error_message="A value for allocation_other_methodology_description should be provided if the allocation_methodology is 'other'",
violation_error_message="A value for allocation_other_methodology_description must be provided if the allocation_methodology is 'other'",
),
]
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ def save_emission_allocation_data(

# Update the emission allocations from the data
for allocations in report_emission_allocations:
# emission_total = allocations.emission_total # TODO: validation should be done with this value to make sure we are not under- or over-allocating
# emission_total = allocations.emission_total # TODO: validation should be done with this value to make sure we are not under- or over-allocating (currently, this validation occurs in the frontend)
for product in allocations.products:
if product.allocated_quantity == 0: # if the allocated quantity is 0, delete any existing allocation
existing_allocation = ReportProductEmissionAllocation.objects.filter(
Expand Down
355 changes: 355 additions & 0 deletions bc_obps/reporting/tests/api/test_report_emission_allocation_api.py

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
from decimal import Decimal
import pytest
from django.core.exceptions import ValidationError
from reporting.models.emission_category import EmissionCategory
from reporting.models.report_product_emission_allocation import ReportProductEmissionAllocation
from common.tests.utils.helpers import BaseTestCase
from registration.tests.constants import TIMESTAMP_COMMON_FIELDS
from reporting.models.report_product import ReportProduct
from model_bakery.baker import make_recipe, make


class ReportProductEmissionAllocationModelTest(BaseTestCase):
@classmethod
def setUpTestData(cls):
facility_report = make_recipe("reporting.tests.utils.facility_report")
product = make_recipe("registration.tests.utils.regulated_product")
emission_category = EmissionCategory.objects.all().first()
report_product = make(
ReportProduct,
report_version=facility_report.report_version,
facility_report=facility_report,
product=product,
)
cls.test_object = make(
ReportProductEmissionAllocation,
report_version=facility_report.report_version,
facility_report=facility_report,
report_product=report_product,
emission_category=emission_category,
allocated_quantity=Decimal('300.4151'),
allocation_methodology='other',
allocation_other_methodology_description='Test description',
)
cls.field_data = [
*TIMESTAMP_COMMON_FIELDS,
("id", "ID", None, None),
("report_version", "report version", None, None),
("facility_report", "facility report", None, None),
("report_product", "report product", None, None),
("emission_category", "emission category", None, None),
("allocated_quantity", "allocated quantity", None, None),
("allocation_methodology", "allocation methodology", 255, None),
("allocation_other_methodology_description", "allocation other methodology description", None, None),
]

def test_allow_null_description_if_methodology_is_not_other(self):
facility_report = make_recipe("reporting.tests.utils.facility_report")
product = make_recipe("registration.tests.utils.regulated_product")
emission_category = EmissionCategory.objects.all().first()
report_product = make(
ReportProduct,
report_version=facility_report.report_version,
facility_report=facility_report,
product=product,
)

with pytest.raises(
ValidationError,
match="A value for allocation_other_methodology_description must be provided if the allocation_methodology is 'other'",
):
make(
ReportProductEmissionAllocation,
report_version=facility_report.report_version,
facility_report=facility_report,
report_product=report_product,
emission_category=emission_category,
allocated_quantity=Decimal('300.4151'),
allocation_methodology=ReportProductEmissionAllocation.AllocationMethodologyChoices.OTHER,
allocation_other_methodology_description=None,
)

# This should not raise
make(
ReportProductEmissionAllocation,
report_version=facility_report.report_version,
facility_report=facility_report,
report_product=report_product,
emission_category=emission_category,
allocated_quantity=Decimal('300.4151'),
allocation_methodology=ReportProductEmissionAllocation.AllocationMethodologyChoices.CALCULATOR,
allocation_other_methodology_description=None,
)

def test_unique_allocation_per_report_product_and_emission_category(self):
facility_report = make_recipe("reporting.tests.utils.facility_report")
product = make_recipe("registration.tests.utils.regulated_product")
emission_category = EmissionCategory.objects.all().first()
report_product = make(
ReportProduct,
report_version=facility_report.report_version,
facility_report=facility_report,
product=product,
)

make(
ReportProductEmissionAllocation,
report_version=facility_report.report_version,
facility_report=facility_report,
report_product=report_product,
emission_category=emission_category,
allocated_quantity=Decimal('300.4151'),
allocation_methodology=ReportProductEmissionAllocation.AllocationMethodologyChoices.CALCULATOR,
allocation_other_methodology_description=None,
)

with pytest.raises(
ValidationError,
match="Report product emission allocation with this Report version, Facility report, Report product and Emission category already exists.",
):
make(
ReportProductEmissionAllocation,
report_version=facility_report.report_version,
facility_report=facility_report,
report_product=report_product,
emission_category=emission_category,
allocated_quantity=Decimal('123.4321'),
allocation_methodology=ReportProductEmissionAllocation.AllocationMethodologyChoices.CALCULATOR,
allocation_other_methodology_description=None,
)
Loading

0 comments on commit 91f80e9

Please sign in to comment.