first ruggedy draft

This commit is contained in:
2026-06-28 13:48:15 +02:00
parent c916f64fcb
commit 1053f6a2a3
78 changed files with 20905 additions and 2 deletions

83
tests/test_ingestion.py Normal file
View File

@@ -0,0 +1,83 @@
from __future__ import annotations
from datetime import date
from decimal import Decimal
from mousehold_api.schemas import ManualObservationCreate, SplitLineCreate
from mousehold_api.services.ingestion import create_observation_with_candidate
from mousehold_domain import FinancialEventStatus, FinancialEventType, ObservationStatus, SourceType
from sqlalchemy.orm import Session
def test_duplicate_observation_is_flagged_without_second_event(
session: Session,
household_setup: dict[str, str],
) -> None:
payload = ManualObservationCreate(
household_id=household_setup["household_id"],
owner_user_id=household_setup["user_a_id"],
source_account_id=household_setup["account_a_id"],
source_reference="same-manual-input",
amount=Decimal("120.00"),
currency="EUR",
event_date=date(2026, 1, 1),
merchant="Groceries",
description="Weekly groceries",
split_lines=[
SplitLineCreate(user_id=household_setup["user_a_id"], share_amount=Decimal("60.00")),
SplitLineCreate(user_id=household_setup["user_b_id"], share_amount=Decimal("60.00")),
],
)
first_observation, first_event = create_observation_with_candidate(session, payload)
second_observation, second_event = create_observation_with_candidate(session, payload)
assert first_observation.status == ObservationStatus.CANDIDATE_CREATED
assert first_event is not None
assert second_observation.status == ObservationStatus.DUPLICATE_SOURCE
assert second_event is None
def test_email_with_due_date_becomes_outstanding_event(
session: Session,
household_setup: dict[str, str],
) -> None:
payload = ManualObservationCreate(
household_id=household_setup["household_id"],
owner_user_id=household_setup["user_a_id"],
source_type=SourceType.KLARNA_EMAIL,
amount=Decimal("84.00"),
currency="EUR",
event_date=date(2026, 1, 3),
due_date=date(2026, 2, 2),
merchant="Klarna Shop",
description="Pay later purchase",
)
_observation, event = create_observation_with_candidate(session, payload)
assert event is not None
assert event.status == FinancialEventStatus.OUTSTANDING
def test_bank_provider_debit_becomes_liability_payment(
session: Session,
household_setup: dict[str, str],
) -> None:
payload = ManualObservationCreate(
household_id=household_setup["household_id"],
owner_user_id=household_setup["user_a_id"],
source_account_id=household_setup["account_a_id"],
source_type=SourceType.BANK_CSV,
amount=Decimal("250.00"),
currency="EUR",
event_date=date(2026, 1, 15),
merchant="Visa Kartenabrechnung",
description="Monthly credit card payment",
)
_observation, event = create_observation_with_candidate(session, payload)
assert event is not None
assert event.event_type == FinancialEventType.LIABILITY_PAYMENT
assert event.status == FinancialEventStatus.CONFIRMED