Skip to content

test: exhaustive pytest coverage#46

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

test: exhaustive pytest coverage#46
deacon-mp wants to merge 1 commit intomasterfrom
test/exhaustive-pytest-coverage

Conversation

@deacon-mp
Copy link
Copy Markdown
Contributor

Summary

  • Adds comprehensive pytest test suite (77 tests) for all compass modules
  • Includes tests/conftest.py with shared fixtures and mock Caldera services
  • Covers app/compass_svc.py endpoints: splash, generate_layer, create_adversary_from_layer
  • Covers all internal methods: _get_layer_boilerplate, _get_all_abilities, _get_adversary_abilities, _extract_techniques, _build_adversary, _read_layer
  • Covers hook.py enable() route registration and module attributes
  • Edge cases: malformed JSON, empty layers, missing fields, raise-vs-return HTTPBadRequest (PR fix: raise instead of return HTTPBadRequest on JSON decode error in compass_svc #45)
  • Adds pytest.ini, tox.ini, .pre-commit-config.yaml, and stub app/service/auth_svc.py for isolated testing

Test plan

  • Run pytest tests/ -v to verify all 77 tests pass

Adds 77 tests covering all public methods and endpoints in compass_svc.py
and hook.py. Includes shared fixtures in conftest.py, edge cases for
malformed/empty layers, missing fields, the raise-vs-return HTTPBadRequest
inconsistency (PR #45), and stub auth_svc for isolated testing.
Copy link
Copy Markdown

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 pytest-based test harness for the Compass plugin, plus local tooling configs (tox/pytest/pre-commit) and minimal stubs so the service can be tested outside the full Caldera runtime.

Changes:

  • Introduces an extensive pytest suite covering CompassService and hook.enable() behavior.
  • Adds local test/tooling configuration (pytest.ini, tox.ini, .pre-commit-config.yaml) to standardize execution and linting.
  • Adds a stub app/service/auth_svc.py (and package init files) to allow isolated imports during tests.

Reviewed changes

Copilot reviewed 7 out of 10 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
tests/test_compass_svc.py Large unit test suite covering CompassService helpers and endpoints, including edge cases.
tests/test_hook.py Tests for hook.py module attributes and route registration in enable().
tests/conftest.py Shared fixtures and stubs/mocks to run Compass tests without Caldera services.
tox.ini Defines tox envs and dependencies to run pytest across multiple Python versions.
pytest.ini Configures pytest discovery and asyncio mode.
.pre-commit-config.yaml Adds formatting/lint hooks (black/flake8 + common checks).
app/service/auth_svc.py Adds decorator stubs to satisfy app.compass_svc imports in isolated tests.
tests/__init__.py Marks tests as a package.
app/__init__.py Marks app as a package for isolated imports.
app/service/__init__.py Marks app.service as a package for isolated imports.

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

Comment on lines +678 to +684
@pytest.mark.asyncio
async def test_json_decode_error_returns_not_raises(self, compass_svc, mock_services):
req = _make_multipart_request(b"invalid json")
# Should NOT raise; should return
resp = await compass_svc.create_adversary_from_layer(req)
assert isinstance(resp, web.HTTPBadRequest)

Comment on lines +2 to +4
import sys
import types
from unittest.mock import AsyncMock, MagicMock, call
Comment on lines +2 to +7
import json
import sys
import types
import uuid
from enum import Enum
from unittest.mock import AsyncMock, MagicMock, patch
Comment on lines +28 to +30
# Now safe to import — app/ has real stub files for auth_svc
from app.compass_svc import CompassService # noqa: E402

@@ -0,0 +1,14 @@
[tox]
envlist = py{39,310,311,312}
Comment on lines +54 to +57
async def test_registers_three_routes(self, mock_app_services):
from hook import enable
services, app, router = mock_app_services
await enable(services)
Comment on lines +19 to +20
def _make_request(body: dict | bytes | None = None, content_type="application/json"):
"""Build a minimal mock aiohttp request carrying *body*."""
Comment on lines +4 to +5
from io import BytesIO
from unittest.mock import AsyncMock, MagicMock, patch
Comment on lines +534 to +540
async def test_malformed_json_returns_400(self, compass_svc, mock_services):
"""PR #45 bug: should *return* HTTPBadRequest, not raise it."""
req = _make_multipart_request(b"<<<not json>>>")
resp = await compass_svc.create_adversary_from_layer(req)
# Current code returns HTTPBadRequest (which is also a Response)
assert isinstance(resp, web.HTTPBadRequest)

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