diff --git a/README.md b/README.md index 951fd595fb4a66f949fca3fd984b146b2ce63850..a32adc3639a8aeacebc639190feedb2b3e3bca62 100644 --- a/README.md +++ b/README.md @@ -31,15 +31,13 @@ async def handle_create(activity: APActivity): await federation.store_object(activity.object) ``` -#### Run Example Usage -- [Server to Server Example](examples/README.md) - #### Documentation -- [Getting Started](documentation/getting-started.md) -- [Configuration Guide](documentation/configuration.md) -- [Architecture Overview](documentation/architecture.md) -- [Security Guide](documentation/security.md) -- [API Reference](documentation/api/) +- [Getting Started](docs/getting-started.md) +- [Configuration Guide](docs/configuration.md) +- [Architecture Overview](docs/architecture.md) +- [Security Guide](docs/security.md) +- [API Reference](docs/api/) +- [Testing Guide](tests/README.md) #### Requirements - Python 3.9+ diff --git a/requirements.txt b/requirements.txt index e926c322d5c36ab2321c07c89eb9a4a3829925f0..d85ddf8033ee189552f150557684cfaa9574737a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -43,6 +43,7 @@ pymongo==4.9.2 pytest==8.3.3 pytest-aiohttp==1.0.5 pytest-asyncio==0.24.0 +pytest-cov==4.1.0 python-dateutil==2.9.0.post0 PyYAML==6.0.2 redis==5.2.0 diff --git a/tests/README.md b/tests/README.md new file mode 100644 index 0000000000000000000000000000000000000000..450a490d6a7f9c4b893d210788d2539bd0f9bd94 --- /dev/null +++ b/tests/README.md @@ -0,0 +1,93 @@ +# PyFed Tests + +This directory contains the test suite for the PyFed library. The tests are written using pytest and are organized into different categories. + +## Directory Structure + +``` +tests/ +├── unit_tests/ # Unit tests for individual components +│ ├── models/ # Tests for ActivityPub models +│ ├── serializers/ # Tests for serialization/deserialization +└── pytest.ini # Pytest configuration +``` + +## Running Tests + +### Prerequisites + +- Python 3.9+ +- pytest +- pytest-asyncio +- pytest-cov + +### Installation + +```bash +pip install . # Install packages +``` + +### Running All Tests + +From the project root directory: + +```bash +pytest +``` + +### Running Specific Test Categories + +```bash +pytest tests/unit_tests/models/ # Run model tests only +pytest tests/unit_tests/serializers/ # Run serializer tests only +pytest tests/integration_tests/ # Run integration tests only +``` + +### Running with Coverage + +```bash +pytest --cov=pyfed tests/ +``` + +### Test Configuration + +The test suite uses the following configuration from `pytest.ini`: + +- `asyncio_mode = auto`: Enables automatic async test detection +- `pythonpath = ../src`: Adds source directory to Python path +- `addopts = --import-mode=importlib`: Uses importlib for imports + +## Writing Tests + +### Test Organization + +- Place unit tests in the appropriate subdirectory under `unit_tests/` +- Use descriptive test names that indicate what is being tested +- Follow the pattern: `test_<what>_<expected_behavior>` + +### Example Test + +```python +def test_serialize_note(): + """Test serialization of a basic Note object.""" + note = APNote( + id="https://example.com/notes/123", + content="Hello, World!" + ) + serialized = note.serialize() + assert serialized["type"] == "Note" + assert serialized["content"] == "Hello, World!" +``` + +## Debugging Tests + +- Use `pytest -v` for verbose output +- Use `pytest -s` to see print statements +- Use `pytest --pdb` to drop into debugger on failures + +## Adding New Tests + +1. Create test files in the appropriate directory +2. Follow existing naming conventions +3. Add necessary imports and fixtures +4. Document test purpose with docstrings \ No newline at end of file diff --git a/tests/unit_tests/models/test_imports.py b/tests/unit_tests/models/test_imports.py index e663a270c5cd134abb1ce9b586f16c226e3350ba..e36f6f1315293e510147b36a333039b01bc3624a 100644 --- a/tests/unit_tests/models/test_imports.py +++ b/tests/unit_tests/models/test_imports.py @@ -65,7 +65,3 @@ def test_can_import_activities(): def test_can_import_serializer(): """Test that the serializer can be imported.""" assert ActivityPubSerializer - -# def test_can_import_plugin_manager(): -# """Test that the plugin manager can be imported.""" -# assert plugin_manager diff --git a/tests/unit_tests/serializers/test_serialization.py b/tests/unit_tests/serializers/test_serialization.py index fbeca7daed172a43d497980e0ce065b481f08ab2..2bfdf0eb99ce6c3b14ed686ee72b90d1fe9b3b76 100644 --- a/tests/unit_tests/serializers/test_serialization.py +++ b/tests/unit_tests/serializers/test_serialization.py @@ -48,14 +48,12 @@ def test_serialize_nested_objects(): """Test serialization of objects with nested objects.""" author = APPerson( id="https://example.com/users/alice", - type="Person", name="Alice", inbox="https://example.com/users/alice/inbox", outbox="https://example.com/users/alice/outbox" ) note = APNote( id="https://example.com/notes/123", - type="Note", content="Hello, World!", attributed_to=author ) @@ -71,13 +69,11 @@ def test_serialize_collection(): items = [ APNote( id=f"https://example.com/notes/{i}", - type="Note", content=f"Note {i}" ).serialize() for i in range(3) ] collection = APCollection( id="https://example.com/collection/1", - type="Collection", total_items=len(items), items=items ) @@ -93,12 +89,10 @@ def test_serialize_activity(): """Test serialization of activities.""" note = APNote( id="https://example.com/notes/123", - type="Note", content="Hello, World!" ).serialize() create = APCreate( id="https://example.com/activities/1", - type="Create", actor="https://example.com/users/alice", object=note ) @@ -156,7 +150,6 @@ def test_serialize_deserialize_complex_object(): """Test round-trip serialization and deserialization.""" original = APNote( id="https://example.com/notes/123", - type="Note", content="Test content", to=["https://example.com/users/bob"], cc=["https://www.w3.org/ns/activitystreams#Public"]