Model/tests/domain/fuel_rates/test_fuel_rates.py
Khalim Conn-Kowlessar bda8a3f276 Expose an off-peak meter's standing charge and full day/night blend range 🟩
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 17:14:51 +00:00

89 lines
2.9 KiB
Python

from __future__ import annotations
import pytest
from domain.fuel_rates.fuel import Fuel, UnpricedFuel
from domain.fuel_rates.fuel_rates import FuelRate, FuelRates, OffPeakRate
def _rates() -> FuelRates:
return FuelRates(
period="test",
seg_export_p_per_kwh=15.0,
rates={Fuel.MAINS_GAS: FuelRate(unit_rate_p_per_kwh=5.74, standing_charge_p_per_day=29.09)},
)
def _off_peak_rates() -> FuelRates:
return FuelRates(
period="test",
seg_export_p_per_kwh=15.0,
rates={},
off_peak=OffPeakRate(
day_p_per_kwh=29.73, night_p_per_kwh=13.89, standing_charge_p_per_day=56.99
),
)
def test_off_peak_blended_rate_at_zero_high_fraction_is_the_night_rate() -> None:
# Arrange — an all-night load (storage heating, high-rate fraction 0.0).
rates = _off_peak_rates()
# Act
blended = rates.off_peak_blended_p_per_kwh(high_rate_fraction=0.0)
# Assert — every kWh bills at the cheap night rate.
assert blended == 13.89
def test_off_peak_blended_rate_at_full_high_fraction_is_the_day_rate() -> None:
# Arrange — an all-day load (high-rate fraction 1.0).
rates = _off_peak_rates()
# Act / Assert — every kWh bills at the dearer day rate.
assert rates.off_peak_blended_p_per_kwh(high_rate_fraction=1.0) == 29.73
def test_off_peak_blended_rate_blends_day_and_night_linearly() -> None:
# Arrange — 25% of the load at the day rate, 75% at night.
rates = _off_peak_rates()
# Act / Assert — 0.25 * 29.73 + 0.75 * 13.89 = 17.85
assert rates.off_peak_blended_p_per_kwh(high_rate_fraction=0.25) == pytest.approx(17.85)
def test_off_peak_blend_without_a_snapshot_off_peak_entry_raises_unpriced_fuel() -> None:
# Arrange — a snapshot that carries no off-peak entry at all.
rates = _rates()
# Act / Assert
with pytest.raises(UnpricedFuel) as excinfo:
rates.off_peak_blended_p_per_kwh(high_rate_fraction=0.5)
assert excinfo.value.fuel is Fuel.ELECTRICITY_OFF_PEAK
def test_off_peak_meter_standing_charge_reads_back() -> None:
# Arrange — the bill adds the off-peak meter's standing charge once per meter.
rates = _off_peak_rates()
# Act / Assert
assert rates.standing_charge_p_per_day(Fuel.ELECTRICITY_OFF_PEAK) == 56.99
def test_unit_rate_and_standing_charge_read_back_for_a_priced_fuel() -> None:
# Arrange
rates = _rates()
# Act / Assert
assert rates.unit_rate_p_per_kwh(Fuel.MAINS_GAS) == 5.74
assert rates.standing_charge_p_per_day(Fuel.MAINS_GAS) == 29.09
def test_a_fuel_absent_from_the_snapshot_raises_unpriced_fuel() -> None:
# Arrange — LPG is not in this snapshot.
rates = _rates()
# Act / Assert — the raise carries the offending fuel for the operator.
with pytest.raises(UnpricedFuel) as excinfo:
rates.unit_rate_p_per_kwh(Fuel.LPG)
assert excinfo.value.fuel is Fuel.LPG