from __future__ import annotations from jarca_ledger_mcp import service def test_category_rules_preview_apply(tmp_path): db_path = str(tmp_path / "ledger.sqlite3") service.create_ledger_transaction("2026-06-01", "expense", 10_000, merchant="이마트에브리데이", raw_summary="체크카드", db_path=db_path) service.create_ledger_transaction("2026-06-02", "expense", 5_000, merchant="알수없음", raw_summary="체크카드", db_path=db_path) seeded = service.seed_default_category_rules(db_path=db_path) assert seeded["success"] is True rules = service.list_category_rules(db_path=db_path) assert rules["count"] > 0 preview = service.preview_categorization(db_path=db_path) assert preview["matched_count"] == 1 assert preview["unmatched_count"] == 1 assert preview["matches"][0]["category"] == "식비" assert preview["matches"][0]["subcategory"] == "마트" applied = service.apply_categorization_rules(db_path=db_path) assert applied["success"] is True assert applied["applied_count"] == 1 categorized = service.list_ledger_transactions(category="식비", db_path=db_path) assert categorized["count"] == 1 uncategorized = service.list_uncategorized_transactions(db_path=db_path) assert uncategorized["count"] == 1 def test_apply_categorization_rules_applies_all_matches_not_just_preview_sample(tmp_path): db_path = str(tmp_path / "ledger.sqlite3") service.seed_default_category_rules(db_path=db_path) for idx in range(150): service.create_ledger_transaction( transaction_date=f"2026-06-{(idx % 28) + 1:02d}", type="expense", amount=10_000 + idx, merchant=f"이마트에브리데이 {idx}", raw_summary="체크카드", db_path=db_path, ) preview = service.preview_categorization(limit=5000, db_path=db_path) assert preview["matched_count"] == 150 assert len(preview["matches"]) == 100 applied = service.apply_categorization_rules(limit=5000, db_path=db_path) assert applied["success"] is True assert applied["applied_count"] == 150 uncategorized = service.list_uncategorized_transactions(limit=200, db_path=db_path) assert uncategorized["count"] == 0 def test_single_category_rule_preview_and_apply_only_uncategorized(tmp_path): db_path = str(tmp_path / "ledger.sqlite3") seeded = service.seed_default_category_rules(db_path=db_path) assert seeded["success"] is True rules = service.list_category_rules(db_path=db_path)["rules"] mart_rule = next(r for r in rules if r["pattern"] == "이마트") uncategorized = service.create_ledger_transaction( "2026-06-01", "expense", 10_000, merchant="이마트에브리데이", raw_summary="체크카드", db_path=db_path )["transaction"] categorized = service.create_ledger_transaction( "2026-06-02", "expense", 20_000, category="생활", subcategory="생필품", merchant="이마트24", raw_summary="체크카드", db_path=db_path )["transaction"] service.create_ledger_transaction( "2026-06-03", "expense", 30_000, merchant="알수없음", raw_summary="체크카드", db_path=db_path ) preview = service.preview_category_rule_matches(mart_rule["id"], db_path=db_path) assert preview["success"] is True assert preview["matched_count"] == 2 assert preview["uncategorized_matched_count"] == 1 assert len(preview["sample"]) == 2 applied = service.apply_category_rule(mart_rule["id"], db_path=db_path) assert applied["success"] is True assert applied["applied_count"] == 1 all_tx = service.list_ledger_transactions(limit=10, db_path=db_path)["transactions"] by_id = {tx["id"]: tx for tx in all_tx} assert by_id[uncategorized["id"]]["category"] == "식비" assert by_id[categorized["id"]]["category"] == "생활"