# tests/services/test_recurring.py import datetime from sqlalchemy import create_engine from sqlalchemy.orm import Session from src.db import Base from src.models import * from src.services.recurring import RecurringDetector def make_session(): engine = create_engine("sqlite:///:memory:") Base.metadata.create_all(engine) return Session(engine) def make_recurring_data(session): member = HouseholdMember(name="Andrew", relationship="self") session.add(member) session.flush() account = Account(name="Checking", institution="WF", account_type="checking", owner_id=member.id) session.add(account) session.flush() # Netflix monthly: ~$19.07 on 3rd/4th of month for month in [1, 2]: session.add(Transaction( date=datetime.date(2026, month, 4), amount=-19.07, description="Netflix.com", account_id=account.id, )) # HelloFresh weekly: ~$142.87 for day in [1, 8, 15, 22, 29]: session.add(Transaction( date=datetime.date(2026, 1, day), amount=-142.87, description="HELLOFRESH", account_id=account.id, )) # Random one-off purchase session.add(Transaction( date=datetime.date(2026, 1, 10), amount=-95.38, description="CARL'S GOLFLAND INC", account_id=account.id, )) session.commit() return account def test_detect_monthly_recurring(): session = make_session() make_recurring_data(session) detector = RecurringDetector(session) results = detector.detect() netflix = [r for r in results if "Netflix" in r["description"]] assert len(netflix) == 1 assert netflix[0]["frequency"] == "monthly" assert abs(netflix[0]["typical_amount"] - 19.07) < 0.01 def test_detect_weekly_recurring(): session = make_session() make_recurring_data(session) detector = RecurringDetector(session) results = detector.detect() hello = [r for r in results if "HELLOFRESH" in r["description"]] assert len(hello) == 1 assert hello[0]["frequency"] == "weekly" def test_one_off_not_detected(): session = make_session() make_recurring_data(session) detector = RecurringDetector(session) results = detector.detect() golf = [r for r in results if "GOLFLAND" in r["description"]] assert len(golf) == 0 def test_annual_cost_calculation(): session = make_session() make_recurring_data(session) detector = RecurringDetector(session) results = detector.detect() netflix = [r for r in results if "Netflix" in r["description"]][0] assert abs(netflix["annual_cost"] - 19.07 * 12) < 1.0