feat: Enhance currency handling and validation across scenarios

- Updated form template to prefill currency input with default value and added help text for clarity.
- Modified integration tests to assert more descriptive error messages for invalid currency codes.
- Introduced new tests for currency normalization and validation in various scenarios, including imports and exports.
- Added comprehensive tests for pricing calculations, ensuring defaults are respected and overrides function correctly.
- Implemented unit tests for pricing settings repository, ensuring CRUD operations and default settings are handled properly.
- Enhanced scenario pricing evaluation tests to validate currency handling and metadata defaults.
- Added simulation tests to ensure Monte Carlo runs are accurate and handle various distribution scenarios.
This commit is contained in:
2025-11-11 18:29:59 +01:00
parent 032e6d2681
commit 795a9f99f4
50 changed files with 5110 additions and 81 deletions

View File

@@ -10,7 +10,15 @@ from sqlalchemy.orm import Session, sessionmaker
from config.database import Base
from config.settings import AdminBootstrapSettings
from services.bootstrap import AdminBootstrapResult, RoleBootstrapResult, bootstrap_admin
from models import MiningOperationType, Project
from services.bootstrap import (
AdminBootstrapResult,
PricingBootstrapResult,
RoleBootstrapResult,
bootstrap_admin,
bootstrap_pricing_settings,
)
from services.pricing import PricingMetadata
from services.unit_of_work import UnitOfWork
@@ -114,3 +122,86 @@ def test_bootstrap_respects_force_reset(unit_of_work_factory: Callable[[], UnitO
user = users_repo.get_by_email(rotated_settings.email)
assert user is not None
assert user.verify_password("rotated")
def test_bootstrap_pricing_creates_defaults(unit_of_work_factory: Callable[[], UnitOfWork]) -> None:
metadata = PricingMetadata(
default_payable_pct=95.0,
default_currency="CAD",
moisture_threshold_pct=3.0,
moisture_penalty_per_pct=1.25,
)
result = bootstrap_pricing_settings(
metadata=metadata,
unit_of_work_factory=unit_of_work_factory,
)
assert isinstance(result, PricingBootstrapResult)
assert result.seed.created is True
assert result.projects_assigned == 0
with unit_of_work_factory() as uow:
settings_repo = uow.pricing_settings
assert settings_repo is not None
stored = settings_repo.get_by_slug("default")
assert stored.default_currency == "CAD"
assert float(stored.default_payable_pct) == pytest.approx(95.0)
assert float(stored.moisture_threshold_pct) == pytest.approx(3.0)
assert float(stored.moisture_penalty_per_pct) == pytest.approx(1.25)
def test_bootstrap_pricing_assigns_projects(unit_of_work_factory: Callable[[], UnitOfWork]) -> None:
metadata = PricingMetadata(
default_payable_pct=90.0,
default_currency="USD",
moisture_threshold_pct=5.0,
moisture_penalty_per_pct=0.5,
)
with unit_of_work_factory() as uow:
projects_repo = uow.projects
assert projects_repo is not None
project = Project(
name="Project Alpha",
operation_type=MiningOperationType.OPEN_PIT,
)
created = projects_repo.create(project)
project_id = created.id
result = bootstrap_pricing_settings(
metadata=metadata,
unit_of_work_factory=unit_of_work_factory,
)
assert result.projects_assigned == 1
assert result.seed.created is True
with unit_of_work_factory() as uow:
projects_repo = uow.projects
assert projects_repo is not None
stored = projects_repo.get(project_id, with_pricing=True)
assert stored.pricing_settings is not None
assert stored.pricing_settings.default_currency == "USD"
def test_bootstrap_pricing_is_idempotent(unit_of_work_factory: Callable[[], UnitOfWork]) -> None:
metadata = PricingMetadata(
default_payable_pct=92.5,
default_currency="EUR",
moisture_threshold_pct=4.5,
moisture_penalty_per_pct=0.75,
)
first = bootstrap_pricing_settings(
metadata=metadata,
unit_of_work_factory=unit_of_work_factory,
)
second = bootstrap_pricing_settings(
metadata=metadata,
unit_of_work_factory=unit_of_work_factory,
)
assert first.seed.created is True
assert second.seed.created is False
assert second.projects_assigned == 0