Files
Chris Farhood 935abf86d4
build-image / build (push) Failing after 18s
Fork intervals-mcp-server: native OAuth + streamable-HTTP, no monkeypatch
- Bump mcp[cli] 1.22 -> 1.28.1 (negotiates MCP protocol 2025-11-25, matching
  current Claude clients; the old 2025-06-18 server never got a tools/list on
  the connector surface).
- Bake transport config into code: stateless_http + json_response for HTTP
  (single JSON body instead of a 34KB SSE stream, which the connector pipeline
  handles far more reliably).
- Bake Authentik OAuth (AuthSettings + JWT TokenVerifier) into intervals_mcp_server.auth,
  configured from MCP_ISSUER/MCP_RESOURCE/MCP_JWKS_URI/MCP_CLIENT_ID — removes the
  runtime FastMCP.__init__ monkeypatch from the k8s deployment command.
- Accept token audience with/without trailing slash (RFC 8707 clients use the
  slash-normalised resource metadata value).
- Dockerfile CMD runs the module (transport via MCP_TRANSPORT); add .gitea CI to
  build+push the image to git.farh.net/farhoodlabs/intervalsicu-mcp.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-04 15:07:46 -04:00

90 lines
2.6 KiB
Plaintext

---
description:
globs:
alwaysApply: true
---
# Testing Patterns and Practices
## Test Organization
Tests are organized in the [tests/](mdc:tests) directory with the following structure:
- **[tests/test_server.py](mdc:tests/test_server.py)** - Main MCP tool testing
- **[tests/test_formatting.py](mdc:tests/test_formatting.py)** - Utility function tests
- **[tests/test_make_intervals_request.py](mdc:tests/test_make_intervals_request.py)** - API communication tests
- **[tests/sample_data.py](mdc:tests/sample_data.py)** - Mock data for testing
## Testing Framework Setup
- **Framework**: pytest with async support (`pytest-asyncio`)
- **Mocking**: pytest-mock for HTTP request mocking
- **Configuration**: Test settings in [pyproject.toml](mdc:pyproject.toml) under `[tool.pytest.ini_options]`
## Testing Patterns
### Async Testing
All MCP tools are async functions, so tests use:
```python
@pytest.mark.asyncio
async def test_function_name():
# Test async MCP tools
```
### Mock API Responses
HTTP requests are mocked using `pytest-mock`:
```python
def test_api_call(mocker):
mock_response = mocker.Mock()
mock_response.json.return_value = {"test": "data"}
mock_response.raise_for_status.return_value = None
mocker.patch("httpx.AsyncClient.get", return_value=mock_response)
```
### Test Data Management
- **Sample Data**: [tests/sample_data.py](mdc:tests/sample_data.py) contains realistic mock data
- **Isolation**: Each test uses fresh mock data to avoid side effects
- **Coverage**: Tests cover both success and error scenarios
## Running Tests
```bash
# Run all tests
pytest
# Run with verbose output
pytest -v
# Run specific test file
pytest tests/test_server.py
# Run with coverage (if installed)
pytest --cov=src/intervals_mcp_server
```
## Test Requirements
Before committing code, ensure:
1. **All tests pass**: `pytest` returns exit code 0
2. **No new linting errors**: `ruff .` passes
3. **Type checking passes**: `mypy src tests` succeeds
## Writing New Tests
When adding new MCP tools or utilities:
1. **Create test cases** in appropriate test file
2. **Mock external dependencies** (HTTP requests, file I/O)
3. **Test both success and error paths**
4. **Use realistic test data** from [tests/sample_data.py](mdc:tests/sample_data.py)
5. **Follow async testing patterns** for MCP tools
6. **Verify error message formatting** for user-facing errors
## Mock Strategy
The project uses comprehensive mocking to:
- **Avoid real API calls** during testing
- **Test error handling** by simulating various HTTP error responses
- **Ensure deterministic results** with controlled test data
- **Speed up test execution** by eliminating network requests