diff --git a/tests/unit/proxy/_experimental/mcp_server/test_openapi_spec_path_url.py b/tests/unit/proxy/_experimental/mcp_server/test_openapi_spec_path_url.py index 5b231aac09d..81ad3cd2bec 100644 --- a/tests/unit/proxy/_experimental/mcp_server/test_openapi_spec_path_url.py +++ b/tests/unit/proxy/_experimental/mcp_server/test_openapi_spec_path_url.py @@ -197,3 +197,52 @@ def test_load_openapi_spec_url_plain_text_body_raises( with pytest.raises(ValueError, match="Expecting value"): gen.load_openapi_spec(url) + + +def test_load_openapi_spec_invalid_yaml_raises(tmp_path) -> None: + """Invalid YAML in a .yaml file must raise ValueError, not crash.""" + p = tmp_path / "openapi.yaml" + p.write_text("openapi: [unclosed\n bad: indent", encoding="utf-8") + with pytest.raises(ValueError, match="Invalid YAML OpenAPI spec"): + gen.load_openapi_spec(str(p)) + + +def test_load_openapi_spec_non_mapping_yaml_raises(tmp_path) -> None: + """A YAML document that is not a mapping must raise TypeError.""" + p = tmp_path / "openapi.yaml" + p.write_text("just a plain string", encoding="utf-8") + with pytest.raises(TypeError, match="expected a JSON/YAML mapping"): + gen.load_openapi_spec(str(p)) + + +def test_load_openapi_spec_missing_file_raises(tmp_path) -> None: + """A missing local spec file must raise FileNotFoundError.""" + with pytest.raises(FileNotFoundError): + gen.load_openapi_spec(str(tmp_path / "does-not-exist.yaml")) + + +def test_load_openapi_spec_json_file_with_yaml_content(tmp_path) -> None: + """A .json file containing YAML falls back to the YAML parser.""" + p = tmp_path / "openapi.json" + p.write_text( + "openapi: '3.0.0'\ninfo:\n title: YAML in JSON clothing\n version: '1.0.0'\npaths: {}", + encoding="utf-8", + ) + spec = gen.load_openapi_spec(str(p)) + assert spec["info"]["title"] == "YAML in JSON clothing" + + +def test_import_yaml_missing_raises_clear_error(monkeypatch: pytest.MonkeyPatch) -> None: + """Without PyYAML installed the error must say how to fix it.""" + import builtins + + real_import = builtins.__import__ + + def fake_import(name, *args, **kwargs): + if name == "yaml": + raise ImportError("No module named 'yaml'") + return real_import(name, *args, **kwargs) + + monkeypatch.setattr(builtins, "__import__", fake_import) + with pytest.raises(ImportError, match="pip install pyyaml"): + gen._import_yaml()