feat(test): add Phase 5b integration and E2E tests

Add comprehensive integration and end-to-end test suites:
- Integration tests for API flows (authorization, token, verification)
- Integration tests for middleware chain and security headers
- Integration tests for domain verification services
- E2E tests for complete authentication flows
- E2E tests for error scenarios and edge cases
- Shared test fixtures and utilities in conftest.py
- Rename Dockerfile to Containerfile for Podman compatibility

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-21 22:22:04 -07:00
parent 01dcaba86b
commit e1f79af347
19 changed files with 4387 additions and 0 deletions

View File

@@ -0,0 +1,137 @@
"""
Integration tests for OAuth 2.0 metadata endpoint.
Tests the /.well-known/oauth-authorization-server endpoint per RFC 8414.
"""
import json
import pytest
from fastapi.testclient import TestClient
@pytest.fixture
def metadata_app(monkeypatch, tmp_path):
"""Create app for metadata testing."""
db_path = tmp_path / "test.db"
monkeypatch.setenv("GONDULF_SECRET_KEY", "a" * 32)
monkeypatch.setenv("GONDULF_BASE_URL", "https://auth.example.com")
monkeypatch.setenv("GONDULF_DATABASE_URL", f"sqlite:///{db_path}")
monkeypatch.setenv("GONDULF_DEBUG", "true")
from gondulf.main import app
return app
@pytest.fixture
def metadata_client(metadata_app):
"""Create test client for metadata tests."""
with TestClient(metadata_app) as client:
yield client
class TestMetadataEndpoint:
"""Tests for OAuth 2.0 Authorization Server Metadata endpoint."""
def test_metadata_returns_json(self, metadata_client):
"""Test metadata endpoint returns JSON response."""
response = metadata_client.get("/.well-known/oauth-authorization-server")
assert response.status_code == 200
assert "application/json" in response.headers["content-type"]
def test_metadata_includes_issuer(self, metadata_client):
"""Test metadata includes issuer field."""
response = metadata_client.get("/.well-known/oauth-authorization-server")
data = response.json()
assert "issuer" in data
assert data["issuer"] == "https://auth.example.com"
def test_metadata_includes_authorization_endpoint(self, metadata_client):
"""Test metadata includes authorization endpoint."""
response = metadata_client.get("/.well-known/oauth-authorization-server")
data = response.json()
assert "authorization_endpoint" in data
assert data["authorization_endpoint"] == "https://auth.example.com/authorize"
def test_metadata_includes_token_endpoint(self, metadata_client):
"""Test metadata includes token endpoint."""
response = metadata_client.get("/.well-known/oauth-authorization-server")
data = response.json()
assert "token_endpoint" in data
assert data["token_endpoint"] == "https://auth.example.com/token"
def test_metadata_includes_response_types(self, metadata_client):
"""Test metadata includes supported response types."""
response = metadata_client.get("/.well-known/oauth-authorization-server")
data = response.json()
assert "response_types_supported" in data
assert "code" in data["response_types_supported"]
def test_metadata_includes_grant_types(self, metadata_client):
"""Test metadata includes supported grant types."""
response = metadata_client.get("/.well-known/oauth-authorization-server")
data = response.json()
assert "grant_types_supported" in data
assert "authorization_code" in data["grant_types_supported"]
def test_metadata_includes_token_auth_methods(self, metadata_client):
"""Test metadata includes token endpoint auth methods."""
response = metadata_client.get("/.well-known/oauth-authorization-server")
data = response.json()
assert "token_endpoint_auth_methods_supported" in data
assert "none" in data["token_endpoint_auth_methods_supported"]
class TestMetadataCaching:
"""Tests for metadata endpoint caching behavior."""
def test_metadata_includes_cache_header(self, metadata_client):
"""Test metadata endpoint includes Cache-Control header."""
response = metadata_client.get("/.well-known/oauth-authorization-server")
assert "Cache-Control" in response.headers
# Should allow caching
assert "public" in response.headers["Cache-Control"]
assert "max-age" in response.headers["Cache-Control"]
def test_metadata_is_cacheable(self, metadata_client):
"""Test metadata endpoint allows public caching."""
response = metadata_client.get("/.well-known/oauth-authorization-server")
cache_control = response.headers["Cache-Control"]
# Should be cacheable for a reasonable time
assert "public" in cache_control
class TestMetadataSecurity:
"""Security tests for metadata endpoint."""
def test_metadata_includes_security_headers(self, metadata_client):
"""Test metadata endpoint includes security headers."""
response = metadata_client.get("/.well-known/oauth-authorization-server")
assert "X-Frame-Options" in response.headers
assert "X-Content-Type-Options" in response.headers
def test_metadata_requires_no_authentication(self, metadata_client):
"""Test metadata endpoint is publicly accessible."""
response = metadata_client.get("/.well-known/oauth-authorization-server")
# Should work without any authentication
assert response.status_code == 200
def test_metadata_returns_valid_json(self, metadata_client):
"""Test metadata returns valid parseable JSON."""
response = metadata_client.get("/.well-known/oauth-authorization-server")
# Should not raise
data = json.loads(response.content)
assert isinstance(data, dict)