import pytest from models import ( AuthModel, RequestModel, ExtractModel, AssertModel, StepModel, TestModel, ) from models.context import Context from models.executor import Executor, Response from models.extractor import Extractor from models.validator import Validator from models.runner import TestRunner, TestResult, StepResult class TestAuthModel: def test_default_values(self): auth = AuthModel() assert auth.type == "none" assert auth.credentials == {} def test_with_credentials(self): auth = AuthModel(type="bearer", credentials={"token": "abc123"}) assert auth.type == "bearer" assert auth.credentials["token"] == "abc123" class TestRequestModel: def test_default_values(self): req = RequestModel() assert req.method == "GET" assert req.path == "/" assert req.headers == {} assert req.query == {} assert req.body is None assert req.body_type == "json" assert req.timeout == 30 def test_custom_values(self): req = RequestModel( method="POST", path="/api/users", headers={"Content-Type": "application/json"}, body={"name": "Test"}, timeout=60, ) assert req.method == "POST" assert req.path == "/api/users" assert req.headers["Content-Type"] == "application/json" assert req.body["name"] == "Test" assert req.timeout == 60 class TestExtractModel: def test_values(self): ext = ExtractModel(name="token", json_path="$.token") assert ext.name == "token" assert ext.json_path == "$.token" assert ext.source == "body" def test_header_source(self): ext = ExtractModel(name="auth", json_path="Authorization", source="header") assert ext.source == "header" class TestAssertModel: def test_status_assert(self): assertion = AssertModel(type="status", value=200) assert assertion.type == "status" assert assertion.value == 200 def test_json_assert(self): assertion = AssertModel(type="json", path="$.id", operator="exists") assert assertion.type == "json" assert assertion.path == "$.id" assert assertion.operator == "exists" class TestStepModel: def test_step_with_request(self): step = StepModel( name="Login", request=RequestModel(method="POST", path="/login"), ) assert step.name == "Login" assert step.request.method == "POST" assert step.extract == [] assert step.assert_ == [] def test_step_with_extracts_and_asserts(self): step = StepModel( name="Login", request=RequestModel(method="POST", path="/login"), extract=[ExtractModel(name="token", json_path="$.token")], assert_=[AssertModel(type="status", value=200)], ) assert len(step.extract) == 1 assert len(step.assert_) == 1 class TestTestModel: def test_default_values(self): model = TestModel() assert model.name == "Unnamed Test" assert model.base_url == "" assert model.variables == {} assert model.auth is None assert model.steps == [] def test_full_model(self): model = TestModel( name="API Test", base_url="http://localhost:8080", variables={"email": "test@x.com"}, auth=AuthModel(type="bearer"), steps=[ StepModel( name="Step1", request=RequestModel(method="GET", path="/"), ) ], ) assert model.name == "API Test" assert model.base_url == "http://localhost:8080" assert model.variables["email"] == "test@x.com" assert model.auth.type == "bearer" assert len(model.steps) == 1 class TestContext: def test_resolve_simple(self): model = TestModel(variables={"name": "Kirill"}) ctx = Context(model) assert ctx.resolve("Hello {{name}}") == "Hello Kirill" def test_resolve_extracted(self): model = TestModel() ctx = Context(model) ctx.set_extracted("token", "abc123") assert ctx.resolve("Bearer {{token}}") == "Bearer abc123" def test_resolve_multiple(self): model = TestModel(variables={"host": "localhost"}) ctx = Context(model) ctx.set_extracted("port", "8080") assert ctx.resolve("{{host}}:{{port}}") == "localhost:8080" def test_resolve_no_variable(self): model = TestModel() ctx = Context(model) assert ctx.resolve("No variables here") == "No variables here" class TestExtractor: def test_extract_from_body(self): model = TestModel() ctx = Context(model) extractor = Extractor(ctx) response = Response(status=200, body={"token": "abc123"}, headers={}) configs = [ExtractModel(name="token", json_path="$.token")] extractor.extract(configs, response) assert ctx.extracted["token"] == "abc123" def test_extract_nested(self): model = TestModel() ctx = Context(model) extractor = Extractor(ctx) response = Response( status=200, body={"user": {"id": 123, "name": "Test"}}, headers={}, ) configs = [ExtractModel(name="user_id", json_path="$.user.id")] extractor.extract(configs, response) assert ctx.extracted["user_id"] == 123 def test_extract_from_status(self): model = TestModel() ctx = Context(model) extractor = Extractor(ctx) response = Response(status=201, body={}, headers={}) configs = [ExtractModel(name="status", json_path="status", source="status")] extractor.extract(configs, response) assert ctx.extracted["status"] == 201 def test_extract_from_header(self): model = TestModel() ctx = Context(model) extractor = Extractor(ctx) response = Response(status=200, body={}, headers={"X-Request-Id": "req-123"}) configs = [ExtractModel(name="req_id", json_path="X-Request-Id", source="header")] extractor.extract(configs, response) assert ctx.extracted["req_id"] == "req-123" class TestValidator: def test_validate_status_success(self): validator = Validator() response = Response(status=200, body={}, headers={}) asserts = [AssertModel(type="status", value=200)] assert validator.validate(asserts, response) is True def test_validate_status_failure(self): validator = Validator() response = Response(status=404, body={}, headers={}) asserts = [AssertModel(type="status", value=200)] assert validator.validate(asserts, response) is False def test_validate_empty_asserts(self): validator = Validator() response = Response(status=200, body={}, headers={}) assert validator.validate([], response) is True class TestExecutor: def test_resolve_url(self): model = TestModel(base_url="http://localhost:8080") ctx = Context(model) executor = Executor(ctx) request = RequestModel(method="GET", path="/api/users") assert executor._resolve_url(request) == "http://localhost:8080/api/users" def test_resolve_url_with_variables(self): model = TestModel(base_url="http://localhost:8080") ctx = Context(model) ctx.set_extracted("user_id", "123") executor = Executor(ctx) request = RequestModel(method="GET", path="/api/users/{{user_id}}") assert executor._resolve_url(request) == "http://localhost:8080/api/users/123" class TestStepResult: def test_step_result(self): response = Response(status=200, body={}, headers={}) result = StepResult(name="Test", passed=True, response=response) assert result.name == "Test" assert result.passed is True assert result.response.status == 200 class TestTestResult: def test_all_passed(self): response = Response(status=200, body={}, headers={}) steps = [ StepResult(name="S1", passed=True, response=response), StepResult(name="S2", passed=True, response=response), ] result = TestResult(steps=steps) assert result.passed is True def test_one_failed(self): response = Response(status=200, body={}, headers={}) steps = [ StepResult(name="S1", passed=True, response=response), StepResult(name="S2", passed=False, response=response), ] result = TestResult(steps=steps) assert result.passed is False def test_empty_steps(self): result = TestResult(steps=[]) assert result.passed is True