diff --git a/tests/test_fuzzer.py b/tests/test_fuzzer.py new file mode 100644 index 0000000..03d7721 --- /dev/null +++ b/tests/test_fuzzer.py @@ -0,0 +1,264 @@ +"""Tests for Fuzzer.""" + +import pytest +from src.core.fuzzer import Fuzzer + + +class TestFuzzer: + """Tests for Fuzzer class.""" + + def test_fuzz_string_returns_invalid_string(self): + """Test that fuzzing string returns edge case values.""" + fuzzer = Fuzzer(seed=42) + + schema = {"type": "string", "minLength": 5} + result = fuzzer.fuzz_string(schema) + + assert isinstance(result, str) + + def test_fuzz_integer_returns_boundary_values(self): + """Test that fuzzing integer returns boundary values.""" + fuzzer = Fuzzer(seed=42) + + schema = {"type": "integer", "minimum": 0, "maximum": 100} + result = fuzzer.fuzz_integer(schema) + + assert isinstance(result, int) + + def test_fuzz_number_returns_special_values(self): + """Test that fuzzing number returns special values.""" + fuzzer = Fuzzer(seed=42) + + schema = {"type": "number"} + result = fuzzer.fuzz_number(schema) + + assert isinstance(result, (int, float)) + + def test_fuzz_boolean_returns_invalid_values(self): + """Test that fuzzing boolean may return non-boolean values.""" + fuzzer = Fuzzer(seed=42) + + schema = {"type": "boolean"} + result = fuzzer.fuzz_boolean(schema) + + assert isinstance(result, (bool, int, str)) + + def test_fuzz_array_returns_edge_cases(self): + """Test that fuzzing array returns edge case arrays.""" + fuzzer = Fuzzer(seed=42) + + schema = {"type": "array", "items": {"type": "string"}} + result = fuzzer.fuzz_array(schema) + + assert isinstance(result, list) + + def test_fuzz_object_returns_edge_cases(self): + """Test that fuzzing object returns edge case objects.""" + fuzzer = Fuzzer(seed=42) + + schema = { + "type": "object", + "properties": { + "id": {"type": "integer"}, + "name": {"type": "string"} + }, + "required": ["id"] + } + result = fuzzer.fuzz_object(schema) + + assert isinstance(result, dict) + + def test_fuzz_null_returns_null(self): + """Test that fuzzing null returns null values.""" + fuzzer = Fuzzer(seed=42) + + schema = {"type": "null"} + result = fuzzer.fuzz_null(schema) + + assert result is None or result in Fuzzer.NULL_VALUES + + def test_fuzz_schema_with_type_string(self): + """Test fuzzing schema with string type.""" + fuzzer = Fuzzer(seed=42) + + schema = {"type": "string", "format": "email"} + result = fuzzer.fuzz_schema(schema) + + assert isinstance(result, str) + + def test_fuzz_schema_with_type_integer(self): + """Test fuzzing schema with integer type.""" + fuzzer = Fuzzer(seed=42) + + schema = {"type": "integer"} + result = fuzzer.fuzz_schema(schema) + + assert isinstance(result, int) + + def test_fuzz_schema_with_type_object(self): + """Test fuzzing schema with object type.""" + fuzzer = Fuzzer(seed=42) + + schema = { + "type": "object", + "properties": { + "user": { + "type": "object", + "properties": { + "id": {"type": "integer"}, + "name": {"type": "string"} + } + } + } + } + result = fuzzer.fuzz_schema(schema) + + assert isinstance(result, dict) + + def test_fuzz_schema_with_empty_schema(self): + """Test fuzzing with empty schema returns None.""" + fuzzer = Fuzzer(seed=42) + + result = fuzzer.fuzz_schema({}) + + assert result is None + + def test_fuzz_schema_with_none_schema(self): + """Test fuzzing with None schema returns None.""" + fuzzer = Fuzzer(seed=42) + + result = fuzzer.fuzz_schema(None) + + assert result is None + + def test_fuzz_request_body(self): + """Test fuzzing request body.""" + fuzzer = Fuzzer(seed=42) + + schema = { + "type": "object", + "properties": { + "name": {"type": "string"}, + "age": {"type": "integer"} + } + } + result = fuzzer.fuzz_request_body(schema) + + assert isinstance(result, (dict, type(None))) + + def test_fuzz_request_body_with_none(self): + """Test fuzzing None request body.""" + fuzzer = Fuzzer(seed=42) + + result = fuzzer.fuzz_request_body(None) + + assert result is None + + def test_fuzz_response(self): + """Test generating fuzzed response.""" + fuzzer = Fuzzer(seed=42) + + schema = {"type": "object", "properties": {"id": {"type": "integer"}}} + result = fuzzer.fuzz_response(schema, status_code=200) + + assert result["status_code"] == 200 + assert "body" in result + + def test_inject_null_values_into_object(self): + """Test injecting null values into object.""" + fuzzer = Fuzzer(seed=42) + + data = {"name": "test", "email": "test@example.com", "age": 25} + result = fuzzer.inject_null_values(data, max_depth=2) + + assert isinstance(result, dict) + + def test_inject_null_values_into_array(self): + """Test injecting null values into array.""" + fuzzer = Fuzzer(seed=42) + + data = [{"name": "test1"}, {"name": "test2"}] + result = fuzzer.inject_null_values(data, max_depth=2) + + assert isinstance(result, list) + assert len(result) == 2 + + def test_create_edge_case_response(self): + """Test creating edge case response.""" + fuzzer = Fuzzer(seed=42) + + schema = {"type": "object", "properties": {"message": {"type": "string"}}} + result = fuzzer.create_edge_case_response(schema) + + assert "status_code" in result + assert "body" in result + + def test_null_values_constant(self): + """Test that NULL_VALUES is defined correctly.""" + assert None in Fuzzer.NULL_VALUES + assert "" in Fuzzer.NULL_VALUES + + def test_invalid_strings_constant(self): + """Test that INVALID_STRINGS contains common edge cases.""" + assert "" in Fuzzer.INVALID_STRINGS + assert "undefined" in Fuzzer.INVALID_STRINGS + + def test_boundary_values_constant(self): + """Test that BOUNDARY_VALUES contains boundary integers.""" + assert -1 in Fuzzer.BOUNDARY_VALUES + assert 0 in Fuzzer.BOUNDARY_VALUES + assert 1 in Fuzzer.BOUNDARY_VALUES + + +class TestFuzzerEdgeCases: + """Tests for fuzzer edge case handling.""" + + def test_fuzz_with_nested_schema(self): + """Test fuzzing deeply nested schema.""" + fuzzer = Fuzzer(seed=42) + + schema = { + "type": "object", + "properties": { + "level1": { + "type": "object", + "properties": { + "level2": { + "type": "object", + "properties": { + "level3": { + "type": "string" + } + } + } + } + } + } + } + + result = fuzzer.fuzz_schema(schema) + + assert isinstance(result, dict) + + def test_fuzz_array_with_complex_items(self): + """Test fuzzing array with complex item schemas.""" + fuzzer = Fuzzer(seed=42) + + schema = { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": {"type": "integer"}, + "name": {"type": "string"}, + "tags": { + "type": "array", + "items": {"type": "string"} + } + } + } + } + + result = fuzzer.fuzz_array(schema) + + assert isinstance(result, list)