"""Unit tests for MCP tool handlers.

Tests the handler-based architecture where each tool has a handler class
with transform_request(), transform_response(), and handle() methods.
"""

from __future__ import annotations

import pytest

from gfp_mcp.tools import (
    BuildCellsHandler,
    CheckConnectivityHandler,
    CheckDrcHandler,
    CheckLvsHandler,
    FreezeCellHandler,
    GenerateBboxHandler,
    GetCellInfoHandler,
    GetPdkInfoHandler,
    GetPortCenterHandler,
    ListCellsHandler,
    SimulateComponentHandler,
    get_handler,
)


def test_all_tools_have_handlers() -> None:
    """Test that all core tools have handlers registered."""
    expected_tools = [
        "build_cells",
        "list_cells",
        "get_cell_info",
        "check_drc",
        "check_connectivity",
        "check_lvs",
        "simulate_component",
    ]
    for tool_name in expected_tools:
        handler = get_handler(tool_name)
        assert handler is not None, f"No handler for tool '{tool_name}'"
        assert handler.mapping is not None, f"No mapping for tool '{tool_name}'"
        assert handler.mapping.method
        assert handler.mapping.path


def test_get_handler_nonexistent() -> None:
    """Test getting a handler for a nonexistent tool."""
    handler = get_handler("nonexistent_tool")
    assert handler is None


def test_build_cells_handler() -> None:
    """Test BuildCellsHandler."""
    handler = BuildCellsHandler()
    assert handler.name == "build_cells"
    assert handler.mapping is not None
    assert handler.mapping.method == "POST"
    assert handler.mapping.path == "/api/build-cells"

    args = {"names": ["cell1", "cell2"], "with_metadata": False}
    transformed = handler.transform_request(args)
    assert "params" in transformed
    assert "json_data" in transformed
    assert transformed["json_data"] == ["cell1", "cell2"]
    assert transformed["params"]["with_metadata"] is False


def test_list_cells_handler() -> None:
    """Test ListCellsHandler."""
    handler = ListCellsHandler()
    assert handler.name == "list_cells"
    assert handler.mapping is not None
    assert handler.mapping.method == "GET"
    assert handler.mapping.path == "/api/cells"

    response = ["cell1", "cell2", "cell3"]
    transformed = handler.transform_response(response)
    assert "cells" in transformed
    assert "count" in transformed
    assert transformed["cells"] == ["cell1", "cell2", "cell3"]
    assert transformed["count"] == 3


def test_get_cell_info_handler() -> None:
    """Test GetCellInfoHandler."""
    handler = GetCellInfoHandler()
    assert handler.name == "get_cell_info"
    assert handler.mapping is not None
    assert handler.mapping.method == "GET"
    assert handler.mapping.path == "/api/cell-info"

    args = {"name": "test_cell"}
    transformed = handler.transform_request(args)
    assert "params" in transformed
    assert transformed["params"]["name"] == "test_cell"


def test_build_cells_request_with_defaults() -> None:
    """Test request transformation with default values."""
    handler = BuildCellsHandler()
    args = {"names": ["test_cell"]}
    transformed = handler.transform_request(args)
    assert transformed["params"]["with_metadata"] is True
    assert transformed["params"]["register"] is True


def test_check_connectivity_handler() -> None:
    """Test CheckConnectivityHandler."""
    handler = CheckConnectivityHandler()
    assert handler.name == "check_connectivity"
    assert handler.mapping is not None
    assert handler.mapping.method == "POST"
    assert handler.mapping.path == "/api/check-connectivity"

    args = {"path": "build/gds/test_cell.gds"}
    transformed = handler.transform_request(args)
    assert "json_data" in transformed
    assert transformed["json_data"]["path"] == "build/gds/test_cell.gds"


def test_check_lvs_handler() -> None:
    """Test CheckLvsHandler."""
    handler = CheckLvsHandler()
    assert handler.name == "check_lvs"
    assert handler.mapping is not None
    assert handler.mapping.method == "POST"
    assert handler.mapping.path == "/api/check-lvs"

    args = {
        "cell": "mzi",
        "netpath": "netlists/mzi.spice",
        "cellargs": '{"length": 10}',
    }
    transformed = handler.transform_request(args)
    assert "json_data" in transformed
    assert transformed["json_data"]["cell"] == "mzi"
    assert transformed["json_data"]["netpath"] == "netlists/mzi.spice"
    assert transformed["json_data"]["cellargs"] == '{"length": 10}'

    args = {"cell": "mzi", "netpath": "netlists/mzi.spice"}
    transformed = handler.transform_request(args)
    assert "json_data" in transformed
    assert transformed["json_data"]["cellargs"] == ""


def test_check_drc_handler() -> None:
    """Test CheckDrcHandler."""
    handler = CheckDrcHandler()
    assert handler.name == "check_drc"
    assert handler.mapping is not None
    assert handler.mapping.method == "POST"
    assert handler.mapping.path == "/api/check-drc"

    args = {"path": "build/gds/test_cell.gds"}
    transformed = handler.transform_request(args)
    assert "json_data" in transformed
    assert transformed["json_data"]["path"] == "build/gds/test_cell.gds"
    assert "pdk" not in transformed["json_data"]
    assert "process" not in transformed["json_data"]

    args = {
        "path": "build/gds/test_cell.gds",
        "pdk": "sky130",
        "process": "A",
        "timeout": 600,
        "host": "https://drc.example.com",
    }
    transformed = handler.transform_request(args)
    assert "json_data" in transformed
    assert transformed["json_data"]["path"] == "build/gds/test_cell.gds"
    assert transformed["json_data"]["pdk"] == "sky130"
    assert transformed["json_data"]["process"] == "A"
    assert transformed["json_data"]["timeout"] == 600
    assert transformed["json_data"]["host"] == "https://drc.example.com"


def test_check_drc_response_with_violations() -> None:
    """Test DRC response transformation with violations."""
    handler = CheckDrcHandler()
    xml_response = """<?xml version="1.0" encoding="utf-8"?>
<report-database>
 <description>DRC Results</description>
 <categories>
  <category>
   <name>Width_Si_Etch1_DF_70nm</name>
   <description>Min width for Si_Etch1_DF_70nm is 0.2 um</description>
  </category>
  <category>
   <name>Space_Si_Etch1_DF_70nm</name>
   <description>Min space for Si_Etch1_DF_70nm is 0.25 um</description>
  </category>
 </categories>
 <cells>
  <cell>
   <name>mzi_100um_with_gratings</name>
  </cell>
 </cells>
 <items>
  <item>
   <category>Width_Si_Etch1_DF_70nm</category>
   <cell>mzi_100um_with_gratings</cell>
   <comment>Min width for Si_Etch1_DF_70nm is 0.2 um</comment>
   <values>
    <value>polygon: (24.576,7.392;24.572,7.402;24.538,7.603;24.546,7.56)</value>
   </values>
  </item>
  <item>
   <category>Space_Si_Etch1_DF_70nm</category>
   <cell>mzi_100um_with_gratings</cell>
   <comment>Min space for Si_Etch1_DF_70nm is 0.25 um</comment>
   <values>
    <value>polygon: (10.0,20.0;10.0,21.0;11.0,21.0;11.0,20.0)</value>
   </values>
  </item>
  <item>
   <category>Space_Si_Etch1_DF_70nm</category>
   <cell>mzi_100um_with_gratings</cell>
   <comment>Min space for Si_Etch1_DF_70nm is 0.25 um</comment>
   <values>
    <value>polygon: (15.5,25.5;16.5,26.5;17.5,25.5)</value>
   </values>
  </item>
 </items>
</report-database>"""

    transformed = handler.transform_response(xml_response)

    assert "summary" in transformed
    assert transformed["summary"]["total_violations"] == 3
    assert transformed["summary"]["total_categories"] == 2
    assert transformed["summary"]["status"] == "FAILED"
    assert "mzi_100um_with_gratings" in transformed["summary"]["cells_checked"]

    assert "violations_by_category" in transformed
    assert len(transformed["violations_by_category"]) == 2
    assert (
        transformed["violations_by_category"][0]["category"] == "Space_Si_Etch1_DF_70nm"
    )
    assert transformed["violations_by_category"][0]["count"] == 2
    assert (
        transformed["violations_by_category"][1]["category"] == "Width_Si_Etch1_DF_70nm"
    )
    assert transformed["violations_by_category"][1]["count"] == 1

    assert "violations" in transformed
    assert len(transformed["violations"]) == 3

    first_violation = transformed["violations"][0]
    assert first_violation["category"] == "Width_Si_Etch1_DF_70nm"
    assert first_violation["cell"] == "mzi_100um_with_gratings"
    assert "location" in first_violation
    assert "bbox" in first_violation["location"]
    assert "centroid" in first_violation["location"]
    assert "size" in first_violation["location"]

    bbox = first_violation["location"]["bbox"]
    assert bbox["min_x"] == 24.538
    assert bbox["max_x"] == 24.576
    assert bbox["min_y"] == 7.392
    assert bbox["max_y"] == 7.603

    centroid = first_violation["location"]["centroid"]
    assert "x" in centroid
    assert "y" in centroid

    size = first_violation["location"]["size"]
    assert size["width"] == round(24.576 - 24.538, 3)
    assert size["height"] == round(7.603 - 7.392, 3)

    assert "recommendations" in transformed
    assert len(transformed["recommendations"]) > 0

    import json

    output_str = json.dumps(transformed)
    assert "polygon:" not in output_str


def test_check_drc_response_no_violations() -> None:
    """Test DRC response with clean design (0 violations)."""
    handler = CheckDrcHandler()
    xml_response = """<?xml version="1.0" encoding="utf-8"?>
<report-database>
 <description>DRC Results</description>
 <categories>
  <category>
   <name>Width_Si_Etch1_DF_70nm</name>
   <description>Min width for Si_Etch1_DF_70nm is 0.2 um</description>
  </category>
 </categories>
 <cells>
  <cell>
   <name>clean_design</name>
  </cell>
 </cells>
 <items>
 </items>
</report-database>"""

    transformed = handler.transform_response(xml_response)

    assert transformed["summary"]["total_violations"] == 0
    assert transformed["summary"]["status"] == "PASSED"
    assert transformed["summary"]["message"] == "No DRC violations found"
    assert transformed["summary"]["total_categories"] == 0

    assert len(transformed["violations_by_category"]) == 0
    assert len(transformed["violations"]) == 0

    assert "Design passes all DRC checks" in transformed["recommendations"]


def test_check_drc_response_invalid_xml() -> None:
    """Test error handling for malformed XML."""
    handler = CheckDrcHandler()
    invalid_xml = "This is not valid XML <malformed>"

    transformed = handler.transform_response(invalid_xml)

    assert "error" in transformed
    assert "Failed to parse DRC XML" in transformed["error"]
    assert "raw_preview" in transformed
    assert "suggestion" in transformed


def test_check_drc_response_json_wrapped() -> None:
    """Test handling of JSON-wrapped XML format."""
    handler = CheckDrcHandler()
    xml_content = """<?xml version="1.0" encoding="utf-8"?>
<report-database>
 <categories></categories>
 <cells>
  <cell><name>test_cell</name></cell>
 </cells>
 <items></items>
</report-database>"""

    json_wrapped = {"content": xml_content}
    transformed = handler.transform_response(json_wrapped)

    assert "summary" in transformed
    assert transformed["summary"]["status"] == "PASSED"
    assert "test_cell" in transformed["summary"]["cells_checked"]


def test_check_drc_response_missing_location() -> None:
    """Test handling of violations without parseable location data."""
    handler = CheckDrcHandler()
    xml_response = """<?xml version="1.0" encoding="utf-8"?>
<report-database>
 <categories>
  <category>
   <name>TestRule</name>
   <description>Test rule description</description>
  </category>
 </categories>
 <cells>
  <cell><name>test_cell</name></cell>
 </cells>
 <items>
  <item>
   <category>TestRule</category>
   <cell>test_cell</cell>
   <comment>Test violation</comment>
   <values>
    <value>invalid format</value>
   </values>
  </item>
  <item>
   <category>TestRule</category>
   <cell>test_cell</cell>
   <comment>Test violation</comment>
   <values>
   </values>
  </item>
 </items>
</report-database>"""

    transformed = handler.transform_response(xml_response)

    assert transformed["summary"]["total_violations"] == 2
    assert len(transformed["violations"]) == 2

    assert "location_warning" in transformed["violations"][0]
    assert (
        transformed["violations"][0]["location_warning"]
        == "Could not parse coordinates"
    )

    assert "location_warning" in transformed["violations"][1]


def test_check_drc_response_unexpected_type() -> None:
    """Test error handling for unexpected response type."""
    handler = CheckDrcHandler()
    transformed = handler.transform_response(123)

    assert "error" in transformed
    assert "Unexpected response type" in transformed["error"]


def test_check_drc_response_file_not_found() -> None:
    """Test error handling when GDS file does not exist."""
    handler = CheckDrcHandler()
    error_response = {
        "detail": "File /Users/test/project/build/mzi.gds does not exist."
    }

    transformed = handler.transform_response(error_response)

    assert "error" in transformed
    assert transformed["error"] == "File not found"
    assert "detail" in transformed
    assert "does not exist" in transformed["detail"]
    assert "suggestion" in transformed
    assert "build_cells" in transformed["suggestion"]


def test_check_drc_response_api_error() -> None:
    """Test error handling for generic FastAPI errors."""
    handler = CheckDrcHandler()
    error_response = {"detail": "Internal server error during DRC check"}

    transformed = handler.transform_response(error_response)

    assert "error" in transformed
    assert transformed["error"] == "DRC check failed"
    assert "detail" in transformed
    assert transformed["detail"] == "Internal server error during DRC check"


def test_check_drc_response_multiple_cells() -> None:
    """Test handling of violations across multiple cells."""
    handler = CheckDrcHandler()
    xml_response = """<?xml version="1.0" encoding="utf-8"?>
<report-database>
 <categories>
  <category>
   <name>Width</name>
   <description>Width violation</description>
  </category>
 </categories>
 <cells>
  <cell><name>cell_a</name></cell>
  <cell><name>cell_b</name></cell>
 </cells>
 <items>
  <item>
   <category>Width</category>
   <cell>cell_a</cell>
   <comment>Width violation</comment>
   <values>
    <value>polygon: (1.0,2.0;3.0,4.0)</value>
   </values>
  </item>
  <item>
   <category>Width</category>
   <cell>cell_b</cell>
   <comment>Width violation</comment>
   <values>
    <value>polygon: (5.0,6.0;7.0,8.0)</value>
   </values>
  </item>
 </items>
</report-database>"""

    transformed = handler.transform_response(xml_response)

    assert len(transformed["summary"]["cells_checked"]) == 2
    assert "cell_a" in transformed["summary"]["cells_checked"]
    assert "cell_b" in transformed["summary"]["cells_checked"]

    assert len(transformed["violations"]) == 2
    cells_in_violations = {v["cell"] for v in transformed["violations"]}
    assert cells_in_violations == {"cell_a", "cell_b"}


def test_check_drc_response_large_violation_count() -> None:
    """Test formatting of large violation counts in recommendations."""
    handler = CheckDrcHandler()
    items_xml = "\n".join(
        [
            f"""  <item>
   <category>SpaceViolation</category>
   <cell>test_cell</cell>
   <comment>Space violation</comment>
   <values>
    <value>polygon: ({i}.0,{i}.0;{i + 1}.0,{i + 1}.0)</value>
   </values>
  </item>"""
            for i in range(150)
        ]
    )

    xml_response = f"""<?xml version="1.0" encoding="utf-8"?>
<report-database>
 <categories>
  <category>
   <name>SpaceViolation</name>
   <description>Space violation</description>
  </category>
 </categories>
 <cells>
  <cell><name>test_cell</name></cell>
 </cells>
 <items>
{items_xml}
 </items>
</report-database>"""

    transformed = handler.transform_response(xml_response)

    assert transformed["summary"]["total_violations"] == 150
    assert len(transformed["violations"]) == 150

    recommendations_str = " ".join(transformed["recommendations"])
    assert "systematic issues" in recommendations_str.lower()


def test_simulate_component_response_transformer() -> None:
    """Test simulate_component response returns path and token count."""
    handler = SimulateComponentHandler()
    # Large mock response simulating S-parameter data
    response = {
        "wavelengths": [1.5 + i * 0.001 for i in range(1000)],
        "sdict": {"o1": {"o2": {"real": [0.5] * 1000, "imag": [0.0] * 1000}}},
        "cached": False,
        "simulation_id": "abc123",
        "file_path": "/path/to/build/simulations/sax/test_abc123.json",
    }

    result = handler.transform_response(response)

    assert result["file_path"] == "/path/to/build/simulations/sax/test_abc123.json"
    assert "estimated_tokens" in result
    assert result["estimated_tokens"] > 0
    assert result["simulation_id"] == "abc123"
    assert result["cached"] is False
    assert "Read tool" in result["note"]
    assert "message" in result

    # Verify the raw S-parameter data is NOT in the response
    assert "wavelengths" not in result
    assert "sdict" not in result


def test_simulate_component_response_transformer_cached() -> None:
    """Test simulate_component response handles cached results."""
    handler = SimulateComponentHandler()
    response = {
        "wavelengths": [1.5, 1.55, 1.6],
        "sdict": {"o1": {"o2": {"real": [0.5, 0.6, 0.7], "imag": [0.0, 0.0, 0.0]}}},
        "cached": True,
        "simulation_id": "cached_abc123",
        "file_path": "/path/to/cached/results.json",
    }

    result = handler.transform_response(response)

    assert result["cached"] is True
    assert result["simulation_id"] == "cached_abc123"
    assert result["file_path"] == "/path/to/cached/results.json"


def test_simulate_component_response_transformer_missing_fields() -> None:
    """Test simulate_component response handles missing optional fields."""
    handler = SimulateComponentHandler()
    response = {
        "wavelengths": [1.5, 1.55],
        "sdict": {},
        # file_path, simulation_id, and cached are missing
    }

    result = handler.transform_response(response)

    assert result["file_path"] is None
    assert result["simulation_id"] is None
    assert result["cached"] is False  # default
    assert "estimated_tokens" in result


def test_simulate_component_response_transformer_unexpected_type() -> None:
    """Test simulate_component response handles unexpected response type."""
    handler = SimulateComponentHandler()
    result = handler.transform_response("not a dict")

    assert "error" in result
    assert "Unexpected response type" in result["error"]
    assert "str" in result["error"]


def test_simulate_component_handler() -> None:
    """Test SimulateComponentHandler endpoint mapping with new SAX API and fallback."""
    handler = SimulateComponentHandler()
    assert handler.name == "simulate_component"
    assert handler.mapping is not None
    assert handler.mapping.method == "POST"
    assert handler.mapping.path == "/api/sax/{name}/simulate"

    args_minimal = {"name": "mzi"}
    transformed = handler.transform_request(args_minimal)

    assert transformed["path"] == "/api/sax/mzi/simulate"
    assert "json_data" in transformed
    json_data = transformed["json_data"]
    assert json_data["layout"] == {}
    assert json_data["model"] == {}
    assert json_data["from_netlist"] is False

    assert transformed["fallback_path"] == "/api/simulate"
    assert "fallback_json_data" in transformed
    fallback_data = transformed["fallback_json_data"]
    assert fallback_data["name"] == "mzi"
    assert fallback_data["layout"] == {}
    assert fallback_data["model"] == {}
    assert fallback_data["how"] == "from_layout"

    args_with_layout = {
        "name": "mzi",
        "layout": {"length_mmi": 12, "gap_mmi": 0.3},
    }
    transformed = handler.transform_request(args_with_layout)
    assert transformed["path"] == "/api/sax/mzi/simulate"
    json_data = transformed["json_data"]
    assert json_data["layout"] == {"length_mmi": 12, "gap_mmi": 0.3}
    assert json_data["model"] == {}
    assert json_data["from_netlist"] is False
    fallback_data = transformed["fallback_json_data"]
    assert fallback_data["name"] == "mzi"
    assert fallback_data["layout"] == {"length_mmi": 12, "gap_mmi": 0.3}
    assert fallback_data["how"] == "from_layout"

    args_with_model = {
        "name": "coupler",
        "model": {"wl": [1.5, 1.55, 1.6], "loss": 0.2},
    }
    transformed = handler.transform_request(args_with_model)
    assert transformed["path"] == "/api/sax/coupler/simulate"
    json_data = transformed["json_data"]
    assert json_data["layout"] == {}
    assert json_data["model"] == {"wl": [1.5, 1.55, 1.6], "loss": 0.2}
    assert json_data["from_netlist"] is False
    fallback_data = transformed["fallback_json_data"]
    assert fallback_data["name"] == "coupler"
    assert fallback_data["model"] == {"wl": [1.5, 1.55, 1.6], "loss": 0.2}

    args_with_how = {
        "name": "ring_resonator",
        "how": "from_netlist",
    }
    transformed = handler.transform_request(args_with_how)
    assert transformed["path"] == "/api/sax/ring_resonator/simulate"
    json_data = transformed["json_data"]
    assert json_data["layout"] == {}
    assert json_data["model"] == {}
    assert json_data["from_netlist"] is True
    fallback_data = transformed["fallback_json_data"]
    assert fallback_data["name"] == "ring_resonator"
    assert fallback_data["how"] == "from_netlist"

    args_complete = {
        "name": "mzi",
        "layout": {"length": 100, "gap": 0.5},
        "model": {"wl": [1.5, 1.55, 1.6], "loss": 0.2},
        "how": "from_layout",
    }
    transformed = handler.transform_request(args_complete)
    assert transformed["path"] == "/api/sax/mzi/simulate"
    json_data = transformed["json_data"]
    assert json_data["layout"] == {"length": 100, "gap": 0.5}
    assert json_data["model"] == {"wl": [1.5, 1.55, 1.6], "loss": 0.2}
    assert json_data["from_netlist"] is False
    fallback_data = transformed["fallback_json_data"]
    assert fallback_data["name"] == "mzi"
    assert fallback_data["layout"] == {"length": 100, "gap": 0.5}
    assert fallback_data["model"] == {"wl": [1.5, 1.55, 1.6], "loss": 0.2}
    assert fallback_data["how"] == "from_layout"


def test_get_port_center_handler() -> None:
    """Test GetPortCenterHandler."""
    handler = GetPortCenterHandler()
    assert handler.name == "get_port_center"
    assert handler.mapping is not None
    assert handler.mapping.method == "GET"
    assert handler.mapping.path == "/api/port-center"

    args = {"netlist": "my_circuit", "instance": "coupler1", "port": "o1"}
    transformed = handler.transform_request(args)
    assert "params" in transformed
    assert transformed["params"]["netlist"] == "my_circuit"
    assert transformed["params"]["instance"] == "coupler1"
    assert transformed["params"]["port"] == "o1"


def test_generate_bbox_handler() -> None:
    """Test GenerateBboxHandler."""
    handler = GenerateBboxHandler()
    assert handler.name == "generate_bbox"
    assert handler.mapping is not None
    assert handler.mapping.method == "POST"
    assert handler.mapping.path == "/api/bbox"

    args = {"path": "build/gds/design.gds"}
    transformed = handler.transform_request(args)
    assert "json_data" in transformed
    assert transformed["json_data"]["path"] == "build/gds/design.gds"
    assert "outpath" not in transformed["json_data"]

    args = {
        "path": "build/gds/design.gds",
        "outpath": "build/gds/design-bbox.gds",
        "layers_to_keep": ["WG", "M1"],
        "bbox_layer": [99, 0],
        "ignore_ports": True,
    }
    transformed = handler.transform_request(args)
    assert "json_data" in transformed
    assert transformed["json_data"]["path"] == "build/gds/design.gds"
    assert transformed["json_data"]["outpath"] == "build/gds/design-bbox.gds"
    assert transformed["json_data"]["layers_to_keep"] == ["WG", "M1"]
    assert transformed["json_data"]["bbox_layer"] == [99, 0]
    assert transformed["json_data"]["ignore_ports"] is True


def test_freeze_cell_handler() -> None:
    """Test FreezeCellHandler."""
    handler = FreezeCellHandler()
    assert handler.name == "freeze_cell"
    assert handler.mapping is not None
    assert handler.mapping.method == "POST"
    assert handler.mapping.path == "/freeze/{cell_name}"

    args = {"cell_name": "mzi"}
    transformed = handler.transform_request(args)
    assert "path" in transformed
    assert transformed["path"] == "/freeze/mzi"
    assert "json_data" in transformed
    assert transformed["json_data"] == {}

    args = {"cell_name": "mzi", "kwargs": {"length": 100, "delta_length": 10}}
    transformed = handler.transform_request(args)
    assert "path" in transformed
    assert transformed["path"] == "/freeze/mzi"
    assert "json_data" in transformed
    assert transformed["json_data"] == {"length": 100, "delta_length": 10}


def test_get_pdk_info_handler() -> None:
    """Test GetPdkInfoHandler."""
    handler = GetPdkInfoHandler()
    assert handler.name == "get_pdk_info"
    assert handler.mapping is not None
    assert handler.mapping.method == "GET"
    assert handler.mapping.path == "/info"

    args: dict[str, str] = {}
    transformed = handler.transform_request(args)
    assert isinstance(transformed, dict)


if __name__ == "__main__":
    pytest.main([__file__, "-v"])
