from __future__ import annotations from io import BytesIO from pathlib import Path import zipfile from civilplan_mcp.config import Settings from civilplan_mcp.tools.land_info_query import ( _read_land_price_from_files, extract_land_use_html_properties, ) from civilplan_mcp.updater import wage_updater def test_extract_land_use_html_properties_reads_regulation_table() -> None: html = """
제2종일반주거지역 60% 200%
건폐율

최대 건폐율 60%

용적률

최대 용적률 200%

""" parsed = extract_land_use_html_properties(html) assert parsed["usedistrictnm"] == "제2종일반주거지역" assert parsed["bcr"] == "60" assert parsed["far"] == "200" def test_read_land_price_from_zip_file(tmp_path: Path, monkeypatch) -> None: land_price_dir = tmp_path / "land_prices" land_price_dir.mkdir() archive_path = land_price_dir / "seoul_land_prices.zip" buffer = BytesIO() with zipfile.ZipFile(buffer, "w") as archive: archive.writestr( "prices.csv", "PNU,LANDPRICE\n1111010100100010000,1250000\n", ) archive_path.write_bytes(buffer.getvalue()) settings = Settings(data_dir=tmp_path) monkeypatch.setattr("civilplan_mcp.tools.land_info_query.get_settings", lambda: settings) price = _read_land_price_from_files("1111010100100010000") assert price == {"individual_m2_won": 1250000, "source": "seoul_land_prices.zip:prices.csv"} def test_update_wage_rates_creates_flag_and_log_on_parse_failure(tmp_path: Path, monkeypatch) -> None: settings = Settings(data_dir=tmp_path) monkeypatch.setattr(wage_updater, "get_settings", lambda: settings) monkeypatch.setattr( wage_updater, "fetch_source_text", lambda url: "No structured wage table here", ) result = wage_updater.update_wage_rates(period="상반기") assert result["status"] == "pending_manual_review" assert (tmp_path / ".update_required_wage").exists() assert (tmp_path / "update_log.json").exists()