Files
Construction-project-master/tests/test_v11_tools.py
2026-04-03 09:08:08 +09:00

160 lines
5.0 KiB
Python

from pathlib import Path
import ezdxf
from civilplan_mcp.config import Settings
from civilplan_mcp.tools.benchmark_validator import validate_against_benchmark
from civilplan_mcp.tools.budget_report_generator import generate_budget_report
from civilplan_mcp.tools.dxf_generator import generate_dxf_drawing
from civilplan_mcp.tools.feasibility_analyzer import analyze_feasibility
from civilplan_mcp.tools.land_info_query import (
build_land_use_bbox_params,
extract_address_result,
extract_feature_properties,
query_land_info,
)
from civilplan_mcp.tools.project_parser import parse_project
from civilplan_mcp.tools.quantity_estimator import estimate_quantities
def test_query_land_info_returns_graceful_message_without_api_keys() -> None:
result = query_land_info(address="경기도 양주시 덕계동 123", pnu=None)
assert result["status"] == "disabled"
def test_settings_keep_public_data_key_for_nara_usage() -> None:
settings = Settings(data_go_kr_api_key="abc")
assert settings.data_go_kr_api_key == "abc"
def test_extract_address_result_reads_vworld_shape() -> None:
payload = {
"response": {
"status": "OK",
"result": {
"point": {"x": "127.061", "y": "37.821"},
"items": [
{
"id": "4163010100101230000",
"address": {"parcel": "경기도 양주시 덕계동 123"}
}
],
},
}
}
parsed = extract_address_result(payload)
assert parsed["pnu"] == "4163010100101230000"
assert parsed["x"] == 127.061
def test_extract_feature_properties_returns_first_feature() -> None:
payload = {
"response": {
"status": "OK",
"result": {
"featureCollection": {
"features": [
{"properties": {"pnu": "4163010100101230000", "jimok": ""}}
]
}
},
}
}
parsed = extract_feature_properties(payload)
assert parsed["jimok"] == ""
def test_build_land_use_bbox_params_uses_wfs_bbox_pattern() -> None:
params = build_land_use_bbox_params(127.0, 37.0, "test-key")
assert params["SERVICE"] == "WFS"
assert params["REQUEST"] == "GetFeature"
assert params["TYPENAME"] == "lt_c_lhblpn"
assert params["SRSNAME"] == "EPSG:4326"
assert params["KEY"] == "test-key"
assert params["OUTPUTFORMAT"] == "application/json"
assert params["BBOX"] == "126.9995,36.9995,127.0005,37.0005,EPSG:4326"
def test_analyze_feasibility_returns_positive_cost_structure() -> None:
result = analyze_feasibility(
land_area_m2=600,
land_price_per_m2=850000,
land_price_multiplier=1.0,
construction_cost_total=890000000,
other_costs_million=50,
revenue_type="임대",
building_floor_area_m2=720,
sale_price_per_m2=None,
monthly_rent_per_m2=16000,
vacancy_rate_pct=10.0,
operating_expense_pct=20.0,
equity_ratio_pct=30.0,
loan_rate_pct=5.5,
loan_term_years=10,
construction_months=24,
sale_months=12,
)
assert result["cost_structure"]["total_investment"] > 0
assert "irr_pct" in result["returns"]
def test_validate_against_benchmark_includes_bid_warning() -> None:
result = validate_against_benchmark(
project_type="소로_도로",
road_length_m=890,
floor_area_m2=None,
region="경기도",
our_estimate_won=1067000000,
)
assert "낙찰가 ≠ 사업비" in result["bid_rate_reference"]["경고"]
def test_generate_budget_report_creates_docx(tmp_path: Path) -> None:
project_data = parse_project(description="복지관 신축 2026~2028 경기도")
project_data["output_dir"] = str(tmp_path)
result = generate_budget_report(
report_type="예산편성요구서",
project_data=project_data,
boq_summary={"total_cost": 1067000000, "direct_cost": 900422000, "indirect_cost": 166578000},
department="도로과",
requester="22B Labs",
output_filename="budget.docx",
)
assert Path(result["file_path"]).exists()
def test_generate_dxf_drawing_creates_dxf(tmp_path: Path) -> None:
project_spec = parse_project(description="소로 신설 L=890m B=6m 경기도")
project_spec["output_dir"] = str(tmp_path)
quantities = estimate_quantities(
road_class="소로",
length_m=890,
width_m=6.0,
terrain="평지",
pavement_type="아스콘",
include_water_supply=False,
include_sewage=False,
include_retaining_wall=False,
include_bridge=False,
bridge_length_m=0.0,
)
result = generate_dxf_drawing(
drawing_type="횡단면도",
project_spec=project_spec,
quantities=quantities,
scale="1:200",
output_filename="road.dxf",
)
doc = ezdxf.readfile(result["file_path"])
assert doc is not None