Skip to content

Add exhaustive pytest suite for Python modules#96

Open
deacon-mp wants to merge 1 commit into
masterfrom
test/exhaustive-pytest-coverage
Open

Add exhaustive pytest suite for Python modules#96
deacon-mp wants to merge 1 commit into
masterfrom
test/exhaustive-pytest-coverage

Conversation

@deacon-mp
Copy link
Copy Markdown
Contributor

Summary

  • Adds 68 pytest tests covering all 3 Python modules: magma_api.py, magma_svc.py, and hook.py
  • Includes conftest.py with Caldera-core stubs so tests run standalone without the full framework
  • Covers: initialization, service wiring, mirror endpoint (echo, error handling, edge cases), plugin lifecycle (enable()), route registration, plugin contract attributes, and dist-serving address conventions
  • Adds pytest.ini for configuration

Modules covered

Module Test file Tests
app/magma_api.py tests/test_magma_api.py 24
app/magma_svc.py tests/test_magma_svc.py 14
hook.py tests/test_hook.py 30

Test plan

  • All 68 tests pass locally (python3 -m pytest tests/ -v)
  • Verify CI pipeline picks up the new test files
  • Confirm no interference with existing Jest frontend tests

Covers all 3 Python modules (magma_api.py, magma_svc.py, hook.py)
with 68 tests across initialization, endpoint behavior, plugin
lifecycle, route registration, and edge cases. Includes Caldera-core
stubs in conftest.py so tests run standalone without the framework.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a standalone Python pytest test suite for the plugin’s Python surface area (API/service modules + hook.py lifecycle), using conftest.py stubs to avoid requiring a full Caldera runtime.

Changes:

  • Adds pytest coverage for app/magma_api.py (mirror) and app/magma_svc.py (foo/wiring).
  • Adds tests for hook.py plugin metadata and enable() lifecycle behavior.
  • Introduces tests/conftest.py Caldera-core import stubs and pytest.ini configuration.

Reviewed changes

Copilot reviewed 5 out of 6 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
tests/test_magma_api.py Exercises MagmaAPI initialization and mirror() echo behavior across payload shapes and error cases.
tests/test_magma_svc.py Covers MagmaService construction/wiring and async foo() behavior.
tests/test_hook.py Validates hook.py module attributes and basic enable() lifecycle expectations.
tests/conftest.py Provides fixtures plus Caldera-core module stubs and import wiring to run tests standalone.
tests/__init__.py Marks/structures the Python test package (empty).
pytest.ini Configures pytest discovery and async mode defaults.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tests/conftest.py
Comment on lines +31 to +100
def _install_caldera_stubs():
"""Create minimal stand-ins for caldera packages that magma imports."""

app_dir = os.path.join(PROJECT_ROOT, "app")

# --- top-level "app" package with __path__ pointing at real dir --------
app_pkg = types.ModuleType("app")
app_pkg.__path__ = [app_dir]
app_pkg.__package__ = "app"

# --- app.utility.base_world -------------------------------------------
app_utility = types.ModuleType("app.utility")
app_utility.__path__ = []
app_utility.__package__ = "app.utility"

base_world_mod = types.ModuleType("app.utility.base_world")

class _Access:
APP = "app"
RED = "red"
BLUE = "blue"

class BaseWorld:
Access = _Access

base_world_mod.BaseWorld = BaseWorld

# --- app.service.auth_svc ---------------------------------------------
app_service = types.ModuleType("app.service")
app_service.__path__ = []
app_service.__package__ = "app.service"

auth_svc_mod = types.ModuleType("app.service.auth_svc")

def check_authorization(func):
return func

def for_all_public_methods(decorator):
def wrapper(cls):
return cls
return wrapper

auth_svc_mod.check_authorization = check_authorization
auth_svc_mod.for_all_public_methods = for_all_public_methods

# --- register them in sys.modules so later imports resolve ------------
mods = {
"app": app_pkg,
"app.utility": app_utility,
"app.utility.base_world": base_world_mod,
"app.service": app_service,
"app.service.auth_svc": auth_svc_mod,
}
for name, mod in mods.items():
sys.modules[name] = mod


_install_caldera_stubs()

# We also need `plugins.magma` to resolve for hook.py's relative import.
_plugins = types.ModuleType("plugins")
_plugins.__path__ = []
_plugins_magma = types.ModuleType("plugins.magma")
_plugins_magma.__path__ = [PROJECT_ROOT]
_plugins_magma_app = types.ModuleType("plugins.magma.app")
_plugins_magma_app.__path__ = [os.path.join(PROJECT_ROOT, "app")]

sys.modules["plugins"] = _plugins
sys.modules["plugins.magma"] = _plugins_magma
sys.modules["plugins.magma.app"] = _plugins_magma_app
Comment thread tests/test_magma_api.py
Comment on lines +17 to +27
def _make_request(body: dict | list | str | None = None, method: str = "POST", path: str = "/"):
"""Build a lightweight mock request whose .read() returns *body* as JSON bytes."""
req = AsyncMock(spec=web.Request)
if body is not None:
payload = json.dumps(body).encode() if not isinstance(body, (bytes, bytearray)) else body
else:
payload = b"{}"
req.read = AsyncMock(return_value=payload)
req.method = method
req.path = path
return req
Comment thread tests/test_hook.py
Comment on lines +64 to +68
@pytest.mark.asyncio
async def test_enable_retrieves_app_svc(self, mock_services, mock_app):
await hook.enable(mock_services)
mock_services["app_svc"].application # accessed as attribute

Comment thread tests/test_magma_svc.py
svc_a = MagmaService(mock_services)
svc_b = MagmaService(mock_services)
assert svc_a is not svc_b
assert svc_a.log is not svc_b.log or svc_a.log.name == svc_b.log.name
Comment thread pytest.ini
@@ -0,0 +1,3 @@
[pytest]
testpaths = tests
asyncio_mode = auto
Comment thread tests/conftest.py
Comment on lines +6 to +11
import logging
from unittest.mock import AsyncMock, MagicMock, patch

import pytest
import pytest_asyncio

Comment thread tests/test_magma_api.py
Comment on lines +4 to +9
from unittest.mock import AsyncMock, MagicMock, patch

import pytest
from aiohttp import web
from aiohttp.test_utils import make_mocked_request

Comment thread tests/test_hook.py
Comment on lines +83 to +87
async def test_enable_accesses_application(self, mock_services, mock_app):
await hook.enable(mock_services)
# The enable function reads app_svc.application
_ = mock_services["app_svc"].application

Comment thread tests/test_hook.py
Comment on lines +3 to +6
import importlib
import sys
import types
from unittest.mock import AsyncMock, MagicMock, patch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants