feat(expenses): add authoritative pre-review workflow
This commit is contained in:
78
server/tests/test_expense_rule_runtime_resilience.py
Normal file
78
server/tests/test_expense_rule_runtime_resilience.py
Normal file
@@ -0,0 +1,78 @@
|
||||
from copy import deepcopy
|
||||
from pathlib import Path
|
||||
from types import SimpleNamespace
|
||||
|
||||
import pytest
|
||||
from openpyxl.utils.exceptions import InvalidFileException
|
||||
|
||||
from app.services.agent_asset_spreadsheet import (
|
||||
COMPANY_TRAVEL_EXPENSE_RULE_CODE,
|
||||
AgentAssetSpreadsheetManager,
|
||||
)
|
||||
from app.services.expense_rule_runtime import ExpenseRuleRuntimeService
|
||||
from app.services.expense_rule_runtime_models import build_default_expense_rule_catalog
|
||||
|
||||
|
||||
def _spreadsheet_asset() -> SimpleNamespace:
|
||||
return SimpleNamespace(
|
||||
code=COMPANY_TRAVEL_EXPENSE_RULE_CODE,
|
||||
config_json={
|
||||
"detail_mode": "spreadsheet",
|
||||
"rule_document": {"storage_key": "corrupted.xlsx"},
|
||||
},
|
||||
current_version="v1.0.0",
|
||||
name="临时损坏规则",
|
||||
)
|
||||
|
||||
|
||||
def _spreadsheet_version() -> SimpleNamespace:
|
||||
return SimpleNamespace(content="", version="v1.0.0")
|
||||
|
||||
|
||||
def _assert_unreadable_workbook_is_skipped(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
workbook_path: Path,
|
||||
) -> None:
|
||||
monkeypatch.setattr(
|
||||
AgentAssetSpreadsheetManager,
|
||||
"resolve_storage_path",
|
||||
lambda _manager, _storage_key: workbook_path,
|
||||
)
|
||||
catalog = build_default_expense_rule_catalog()
|
||||
default_catalog = deepcopy(catalog)
|
||||
|
||||
ExpenseRuleRuntimeService(db=None)._apply_spreadsheet_runtime_payload(
|
||||
catalog,
|
||||
asset=_spreadsheet_asset(),
|
||||
version=_spreadsheet_version(),
|
||||
)
|
||||
|
||||
assert catalog == default_catalog
|
||||
assert catalog.travel_policy is not None
|
||||
assert catalog.scene_policies
|
||||
|
||||
|
||||
def test_corrupted_spreadsheet_is_skipped_without_breaking_default_catalog(
|
||||
tmp_path: Path,
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
corrupted_workbook = tmp_path / "corrupted.xlsx"
|
||||
corrupted_workbook.write_bytes(b"not-an-xlsx-archive")
|
||||
|
||||
_assert_unreadable_workbook_is_skipped(monkeypatch, corrupted_workbook)
|
||||
|
||||
|
||||
def test_invalid_spreadsheet_format_is_skipped_without_breaking_catalog(
|
||||
tmp_path: Path,
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
invalid_workbook = tmp_path / "invalid.xlsx"
|
||||
invalid_workbook.touch()
|
||||
monkeypatch.setattr(
|
||||
"app.services.expense_rule_runtime.load_workbook",
|
||||
lambda *_args, **_kwargs: (_ for _ in ()).throw(
|
||||
InvalidFileException("unsupported workbook format")
|
||||
),
|
||||
)
|
||||
|
||||
_assert_unreadable_workbook_is_skipped(monkeypatch, invalid_workbook)
|
||||
Reference in New Issue
Block a user