import pytest from pathlib import Path import tempfile import os from yamlreaders import YamlReader, PostmanReader, OpenAPIReader, get_reader from yamlreaders.base import BaseReader, ParseError TESTS_DIR = Path(__file__).parent EXAMPLES_DIR = TESTS_DIR.parent / "examples" class TestBaseReader: def test_is_abstract(self): with pytest.raises(TypeError): BaseReader() class TestYamlReader: def test_validate_valid(self): reader = YamlReader() assert reader.validate(EXAMPLES_DIR / "custom.yaml") is True def test_validate_invalid(self): reader = YamlReader() with tempfile.NamedTemporaryFile(mode="w", suffix=".yaml", delete=False) as f: f.write("invalid: yaml\ncontent: here") f.flush() result = reader.validate(f.name) os.unlink(f.name) assert result is False def test_parse(self): reader = YamlReader() model = reader.parse(EXAMPLES_DIR / "custom.yaml") assert model.name == "Test Authorization" assert model.base_url == "http://localhost:8080" assert model.variables["email"] == "test@example.com" assert model.variables["password"] == "Test123!" assert len(model.steps) == 3 def test_parse_step_name(self): reader = YamlReader() model = reader.parse(EXAMPLES_DIR / "custom.yaml") assert model.steps[0].name == "Register User" assert model.steps[1].name == "Login" assert model.steps[2].name == "Get Profile" def test_parse_request(self): reader = YamlReader() model = reader.parse(EXAMPLES_DIR / "custom.yaml") req = model.steps[0].request assert req.method == "POST" assert req.path == "/api/register" assert req.headers["Content-Type"] == "application/json" assert req.body["email"] == "{{email}}" def test_parse_extract(self): reader = YamlReader() model = reader.parse(EXAMPLES_DIR / "custom.yaml") extract = model.steps[0].extract assert len(extract) == 1 assert extract[0].name == "user_id" assert extract[0].json_path == "$.id" def test_parse_assert(self): reader = YamlReader() model = reader.parse(EXAMPLES_DIR / "custom.yaml") asserts = model.steps[0].assert_ assert len(asserts) == 1 assert asserts[0].type == "status" assert asserts[0].value == 201 def test_parse_step_without_name_fails(self): reader = YamlReader() with tempfile.NamedTemporaryFile(mode="w", suffix=".yaml", delete=False) as f: f.write("steps:\n - request:\n method: GET\n url: /") f.flush() with pytest.raises(ParseError): reader.parse(f.name) os.unlink(f.name) def test_parse_step_without_request_fails(self): reader = YamlReader() with tempfile.NamedTemporaryFile(mode="w", suffix=".yaml", delete=False) as f: f.write("steps:\n - name: Test") f.flush() with pytest.raises(ParseError): reader.parse(f.name) os.unlink(f.name) class TestPostmanReader: def test_validate_valid(self): reader = PostmanReader() assert reader.validate(EXAMPLES_DIR / "postman.yaml") is True def test_parse(self): reader = PostmanReader() model = reader.parse(EXAMPLES_DIR / "postman.yaml") assert model.name == "Test Collection" assert model.base_url == "http://localhost:8080" assert model.variables["email"] == "test@example.com" assert len(model.steps) == 2 def test_parse_step_names(self): reader = PostmanReader() model = reader.parse(EXAMPLES_DIR / "postman.yaml") assert model.steps[0].name == "Login" assert model.steps[1].name == "Get Profile" def test_parse_request_method(self): reader = PostmanReader() model = reader.parse(EXAMPLES_DIR / "postman.yaml") assert model.steps[0].request.method == "POST" assert model.steps[1].request.method == "GET" def test_parse_request_headers(self): reader = PostmanReader() model = reader.parse(EXAMPLES_DIR / "postman.yaml") headers = model.steps[0].request.headers assert headers["Content-Type"] == "application/json" def test_parse_request_body(self): reader = PostmanReader() model = reader.parse(EXAMPLES_DIR / "postman.yaml") body = model.steps[0].request.body assert body["email"] == "{{email}}" assert body["password"] == "Test123!" def test_parse_nested_items(self): reader = PostmanReader() with tempfile.NamedTemporaryFile(mode="w", suffix=".yaml", delete=False) as f: f.write(""" info: name: Nested item: - name: Folder item: - name: Nested Request request: method: GET url: /nested """) f.flush() model = reader.parse(f.name) os.unlink(f.name) assert len(model.steps) == 1 assert model.steps[0].name == "Nested Request" def test_validate_invalid(self): reader = PostmanReader() with tempfile.NamedTemporaryFile(mode="w", suffix=".yaml", delete=False) as f: f.write("info: {}\nother: data") f.flush() assert reader.validate(f.name) is False os.unlink(f.name) class TestOpenAPIReader: def test_validate_valid(self): reader = OpenAPIReader() assert reader.validate(EXAMPLES_DIR / "openapi.yaml") is True def test_parse(self): reader = OpenAPIReader() model = reader.parse(EXAMPLES_DIR / "openapi.yaml") assert model.name == "Test API" assert model.base_url == "http://localhost:8080" assert len(model.steps) == 2 def test_parse_step_names(self): reader = OpenAPIReader() model = reader.parse(EXAMPLES_DIR / "openapi.yaml") names = [s.name for s in model.steps] assert "loginUser" in names assert "getProfile" in names def test_parse_request_methods(self): reader = OpenAPIReader() model = reader.parse(EXAMPLES_DIR / "openapi.yaml") methods = [s.request.method for s in model.steps] assert "POST" in methods assert "GET" in methods def test_parse_request_paths(self): reader = OpenAPIReader() model = reader.parse(EXAMPLES_DIR / "openapi.yaml") paths = [s.request.path for s in model.steps] assert "/api/login" in paths assert "/api/profile" in paths def test_parse_generates_asserts(self): reader = OpenAPIReader() model = reader.parse(EXAMPLES_DIR / "openapi.yaml") for step in model.steps: assert len(step.assert_) > 0 assert step.assert_[0].type == "status" assert step.assert_[0].value == 200 def test_parse_with_servers(self): reader = OpenAPIReader() with tempfile.NamedTemporaryFile(mode="w", suffix=".yaml", delete=False) as f: f.write(""" openapi: "3.0.0" info: title: Test version: "1.0" servers: - url: https://api.example.com/v1 paths: /test: get: operationId: test responses: "200": description: OK """) f.flush() model = reader.parse(f.name) os.unlink(f.name) assert model.base_url == "https://api.example.com/v1" def test_validate_invalid(self): reader = OpenAPIReader() with tempfile.NamedTemporaryFile(mode="w", suffix=".yaml", delete=False) as f: f.write("swagger: '2.0'\ninfo:\n title: Test") f.flush() assert reader.validate(f.name) is False os.unlink(f.name) class TestGetReader: def test_auto_detect_yaml(self): reader = get_reader(EXAMPLES_DIR / "custom.yaml") assert isinstance(reader, YamlReader) def test_auto_detect_postman(self): reader = get_reader(EXAMPLES_DIR / "postman.yaml") assert isinstance(reader, PostmanReader) def test_auto_detect_openapi(self): reader = get_reader(EXAMPLES_DIR / "openapi.yaml") assert isinstance(reader, OpenAPIReader) def test_file_not_found(self): with pytest.raises(FileNotFoundError): get_reader("nonexistent.yaml")