170 lines
5.6 KiB
Python
170 lines
5.6 KiB
Python
"""
|
|
Tests for encoder.py - JSON encoding utilities.
|
|
|
|
This test suite provides comprehensive coverage for the Encoder class:
|
|
- Tests serialization of various Python types
|
|
- Tests special handling of Path objects
|
|
- Tests DateRange serialization
|
|
- Tests date serialization
|
|
- Tests ImpersonateTarget serialization
|
|
- Tests ItemDTO serialization
|
|
- Tests object serialization with serialize() method
|
|
- Tests object serialization with __dict__ fallback
|
|
- Tests fallback to default JSONEncoder behavior
|
|
|
|
Total test functions: 10
|
|
All supported types and edge cases are covered.
|
|
"""
|
|
|
|
import json
|
|
from datetime import date
|
|
from pathlib import Path
|
|
from unittest.mock import MagicMock
|
|
|
|
import pytest
|
|
|
|
from app.library.encoder import Encoder
|
|
|
|
|
|
class TestEncoder:
|
|
"""Test the Encoder class."""
|
|
|
|
def setup_method(self):
|
|
"""Set up test fixtures."""
|
|
self.encoder = Encoder()
|
|
|
|
def test_path_serialization(self):
|
|
"""Test that Path objects are serialized as strings."""
|
|
path = Path("/tmp/test/file.txt")
|
|
result = self.encoder.default(path)
|
|
assert result == "/tmp/test/file.txt"
|
|
assert isinstance(result, str)
|
|
|
|
def test_path_serialization_relative(self):
|
|
"""Test that relative Path objects are serialized correctly."""
|
|
path = Path("relative/path/file.txt")
|
|
result = self.encoder.default(path)
|
|
assert result == "relative/path/file.txt"
|
|
|
|
def test_date_serialization(self):
|
|
"""Test that date objects are serialized as strings."""
|
|
test_date = date(2024, 3, 15)
|
|
result = self.encoder.default(test_date)
|
|
assert result == "2024-03-15"
|
|
|
|
def test_object_with_serialize_method(self):
|
|
"""Test that objects with serialize method use it."""
|
|
class CustomObject:
|
|
def serialize(self):
|
|
return {"custom": "data", "type": "test"}
|
|
|
|
obj = CustomObject()
|
|
result = self.encoder.default(obj)
|
|
assert result == {"custom": "data", "type": "test"}
|
|
|
|
def test_object_with_dict_fallback(self):
|
|
"""Test that objects without serialize method fall back to __dict__."""
|
|
class SimpleObject:
|
|
def __init__(self):
|
|
self.name = "test"
|
|
self.value = 42
|
|
|
|
obj = SimpleObject()
|
|
result = self.encoder.default(obj)
|
|
assert result == {"name": "test", "value": 42}
|
|
|
|
def test_object_without_dict_fallback_to_default(self):
|
|
"""Test that objects without __dict__ fall back to default JSONEncoder."""
|
|
# This should raise TypeError since complex is not JSON serializable
|
|
with pytest.raises(TypeError):
|
|
self.encoder.default(complex(1, 2))
|
|
|
|
def test_json_dumps_integration(self):
|
|
"""Test full JSON serialization with various types."""
|
|
data = {
|
|
"path": Path("/tmp/test.txt"),
|
|
"date": date(2024, 1, 1),
|
|
"number": 42,
|
|
"string": "test"
|
|
}
|
|
|
|
result = json.dumps(data, cls=Encoder)
|
|
parsed = json.loads(result)
|
|
|
|
assert parsed["path"] == "/tmp/test.txt"
|
|
assert parsed["date"] == "2024-01-01"
|
|
assert parsed["number"] == 42
|
|
assert parsed["string"] == "test"
|
|
|
|
def test_json_dumps_with_custom_object(self):
|
|
"""Test JSON serialization with custom objects."""
|
|
class TestObject:
|
|
def __init__(self):
|
|
self.name = "test"
|
|
self.items = [1, 2, 3]
|
|
|
|
data = {
|
|
"object": TestObject(),
|
|
"regular": "data"
|
|
}
|
|
|
|
result = json.dumps(data, cls=Encoder)
|
|
parsed = json.loads(result)
|
|
|
|
assert parsed["object"]["name"] == "test"
|
|
assert parsed["object"]["items"] == [1, 2, 3]
|
|
assert parsed["regular"] == "data"
|
|
|
|
def test_nested_serialization(self):
|
|
"""Test serialization of nested structures with various types."""
|
|
class CustomObj:
|
|
def serialize(self):
|
|
return {"serialized": True}
|
|
|
|
data = {
|
|
"paths": [Path("/tmp/1.txt"), Path("/tmp/2.txt")],
|
|
"dates": [date(2024, 1, 1), date(2024, 12, 31)],
|
|
"custom": CustomObj(),
|
|
"nested": {
|
|
"path": Path("/nested/path"),
|
|
"date": date(2024, 6, 15)
|
|
}
|
|
}
|
|
|
|
result = json.dumps(data, cls=Encoder)
|
|
parsed = json.loads(result)
|
|
|
|
assert parsed["paths"] == ["/tmp/1.txt", "/tmp/2.txt"]
|
|
assert parsed["dates"] == ["2024-01-01", "2024-12-31"]
|
|
assert parsed["custom"] == {"serialized": True}
|
|
assert parsed["nested"]["path"] == "/nested/path"
|
|
assert parsed["nested"]["date"] == "2024-06-15"
|
|
|
|
def test_mock_daterange_serialization(self):
|
|
"""Test DateRange serialization with mock object."""
|
|
# Mock a DateRange-like object
|
|
mock_daterange = MagicMock()
|
|
mock_daterange.start = date(2024, 1, 15)
|
|
mock_daterange.end = date(2024, 12, 31)
|
|
|
|
# Mock isinstance to return True for DateRange
|
|
import builtins
|
|
original_isinstance = builtins.isinstance
|
|
|
|
def mock_isinstance(obj, cls):
|
|
if obj is mock_daterange and hasattr(cls, "__name__") and "DateRange" in str(cls):
|
|
return True
|
|
return original_isinstance(obj, cls)
|
|
|
|
builtins.isinstance = mock_isinstance
|
|
|
|
try:
|
|
result = self.encoder.default(mock_daterange)
|
|
expected = {"start": "20240115", "end": "20241231"}
|
|
assert result == expected
|
|
finally:
|
|
builtins.isinstance = original_isinstance
|
|
|
|
|
|
if __name__ == "__main__":
|
|
pytest.main([__file__])
|