feat: BreakPilot PWA - Full codebase (clean push without large binaries)
Some checks failed
Tests / Go Tests (push) Has been cancelled
Tests / Python Tests (push) Has been cancelled
Tests / Integration Tests (push) Has been cancelled
Tests / Go Lint (push) Has been cancelled
Tests / Python Lint (push) Has been cancelled
Tests / Security Scan (push) Has been cancelled
Tests / All Checks Passed (push) Has been cancelled
Security Scanning / Secret Scanning (push) Has been cancelled
Security Scanning / Dependency Vulnerability Scan (push) Has been cancelled
Security Scanning / Go Security Scan (push) Has been cancelled
Security Scanning / Python Security Scan (push) Has been cancelled
Security Scanning / Node.js Security Scan (push) Has been cancelled
Security Scanning / Docker Image Security (push) Has been cancelled
Security Scanning / Security Summary (push) Has been cancelled
CI/CD Pipeline / Go Tests (push) Has been cancelled
CI/CD Pipeline / Python Tests (push) Has been cancelled
CI/CD Pipeline / Website Tests (push) Has been cancelled
CI/CD Pipeline / Linting (push) Has been cancelled
CI/CD Pipeline / Security Scan (push) Has been cancelled
CI/CD Pipeline / Docker Build & Push (push) Has been cancelled
CI/CD Pipeline / Integration Tests (push) Has been cancelled
CI/CD Pipeline / Deploy to Staging (push) Has been cancelled
CI/CD Pipeline / Deploy to Production (push) Has been cancelled
CI/CD Pipeline / CI Summary (push) Has been cancelled
ci/woodpecker/manual/build-ci-image Pipeline was successful
ci/woodpecker/manual/main Pipeline failed

All services: admin-v2, studio-v2, website, ai-compliance-sdk,
consent-service, klausur-service, voice-service, and infrastructure.
Large PDFs and compiled binaries excluded via .gitignore.
This commit is contained in:
BreakPilot Dev
2026-02-11 13:25:58 +01:00
commit 19855efacc
2512 changed files with 933814 additions and 0 deletions

View File

@@ -0,0 +1,294 @@
"""
Tests for Recording API
Tests for Jibri webhook handling, recording management, and transcription endpoints.
"""
import pytest
from datetime import datetime, timedelta
from fastapi.testclient import TestClient
# Import the app (adjust import path as needed)
# In actual test environment, this would be the main FastAPI app
# from main import app
# For now, we create a minimal test setup
from fastapi import FastAPI
from recording_api import router as recording_router
app = FastAPI()
app.include_router(recording_router)
client = TestClient(app)
class TestJibriWebhook:
"""Tests for Jibri webhook endpoint."""
def test_webhook_recording_completed_valid(self):
"""Test webhook with valid recording_completed event."""
payload = {
"event": "recording_completed",
"recording_name": "test-room_20260115_120000",
"storage_path": "recordings/test-room_20260115_120000/video.mp4",
"audio_path": "recordings/test-room_20260115_120000/audio.wav",
"file_size_bytes": 52428800,
"timestamp": "2026-01-15T12:00:00Z"
}
response = client.post("/api/recordings/webhook", json=payload)
assert response.status_code == 200
data = response.json()
assert data["success"] is True
assert data["status"] == "uploaded"
assert "recording_id" in data
assert data["meeting_id"] == "test-room"
def test_webhook_unknown_event_rejected(self):
"""Test that unknown event types are rejected."""
payload = {
"event": "unknown_event",
"recording_name": "test",
"storage_path": "test/video.mp4",
"file_size_bytes": 1000,
"timestamp": "2026-01-15T12:00:00Z"
}
response = client.post("/api/recordings/webhook", json=payload)
assert response.status_code == 400
assert "Unknown event type" in response.json()["error"]
def test_webhook_missing_required_fields(self):
"""Test that missing required fields cause validation error."""
payload = {
"event": "recording_completed"
# Missing other required fields
}
response = client.post("/api/recordings/webhook", json=payload)
assert response.status_code == 422 # Validation error
class TestRecordingManagement:
"""Tests for recording CRUD operations."""
@pytest.fixture(autouse=True)
def setup(self):
"""Create a test recording before each test."""
# Clear store and create test recording
from recording_api import _recordings_store
_recordings_store.clear()
payload = {
"event": "recording_completed",
"recording_name": "fixture-room_20260115_100000",
"storage_path": "recordings/fixture-room/video.mp4",
"file_size_bytes": 10000000,
"timestamp": "2026-01-15T10:00:00Z"
}
response = client.post("/api/recordings/webhook", json=payload)
self.recording_id = response.json()["recording_id"]
def test_list_recordings_empty(self):
"""Test listing recordings when empty."""
from recording_api import _recordings_store
_recordings_store.clear()
response = client.get("/api/recordings")
assert response.status_code == 200
data = response.json()
assert data["total"] == 0
assert data["recordings"] == []
def test_list_recordings_with_data(self):
"""Test listing recordings returns created recordings."""
response = client.get("/api/recordings")
assert response.status_code == 200
data = response.json()
assert data["total"] == 1
assert len(data["recordings"]) == 1
def test_list_recordings_filter_by_status(self):
"""Test filtering recordings by status."""
response = client.get("/api/recordings?status=uploaded")
assert response.status_code == 200
data = response.json()
assert all(r["status"] == "uploaded" for r in data["recordings"])
def test_list_recordings_pagination(self):
"""Test pagination of recordings list."""
response = client.get("/api/recordings?page=1&page_size=10")
assert response.status_code == 200
data = response.json()
assert data["page"] == 1
assert data["page_size"] == 10
def test_get_recording_by_id(self):
"""Test getting a specific recording by ID."""
response = client.get(f"/api/recordings/{self.recording_id}")
assert response.status_code == 200
data = response.json()
assert data["id"] == self.recording_id
assert data["status"] == "uploaded"
def test_get_recording_not_found(self):
"""Test getting non-existent recording returns 404."""
response = client.get("/api/recordings/nonexistent-id")
assert response.status_code == 404
assert "not found" in response.json()["detail"].lower()
def test_delete_recording(self):
"""Test soft-deleting a recording."""
response = client.delete(
f"/api/recordings/{self.recording_id}?reason=DSGVO%20request"
)
assert response.status_code == 200
data = response.json()
assert data["success"] is True
assert data["status"] == "deleted"
def test_delete_recording_requires_reason(self):
"""Test that deletion requires a reason."""
response = client.delete(f"/api/recordings/{self.recording_id}")
assert response.status_code == 422 # Missing required query param
class TestTranscriptionEndpoints:
"""Tests for transcription management."""
@pytest.fixture(autouse=True)
def setup(self):
"""Create test recording and clear transcription store."""
from recording_api import _recordings_store, _transcriptions_store
_recordings_store.clear()
_transcriptions_store.clear()
payload = {
"event": "recording_completed",
"recording_name": "trans-test_20260115_110000",
"storage_path": "recordings/trans-test/video.mp4",
"file_size_bytes": 5000000,
"timestamp": "2026-01-15T11:00:00Z"
}
response = client.post("/api/recordings/webhook", json=payload)
self.recording_id = response.json()["recording_id"]
def test_start_transcription(self):
"""Test starting a transcription job."""
response = client.post(
f"/api/recordings/{self.recording_id}/transcribe",
json={"language": "de", "model": "large-v3"}
)
assert response.status_code == 200
data = response.json()
assert data["status"] == "pending"
assert data["language"] == "de"
assert data["model"] == "large-v3"
def test_start_transcription_default_values(self):
"""Test transcription uses default values when not specified."""
response = client.post(
f"/api/recordings/{self.recording_id}/transcribe",
json={}
)
assert response.status_code == 200
data = response.json()
assert data["language"] == "de"
assert data["model"] == "large-v3"
def test_start_transcription_recording_not_found(self):
"""Test starting transcription for non-existent recording."""
response = client.post(
"/api/recordings/nonexistent/transcribe",
json={"language": "de"}
)
assert response.status_code == 404
def test_start_transcription_duplicate_rejected(self):
"""Test that duplicate transcription requests are rejected."""
# First request
client.post(
f"/api/recordings/{self.recording_id}/transcribe",
json={"language": "de"}
)
# Second request should fail
response = client.post(
f"/api/recordings/{self.recording_id}/transcribe",
json={"language": "de"}
)
assert response.status_code == 409
assert "already exists" in response.json()["detail"]
def test_get_transcription_status(self):
"""Test getting transcription status."""
# Start transcription first
client.post(
f"/api/recordings/{self.recording_id}/transcribe",
json={"language": "de"}
)
response = client.get(
f"/api/recordings/{self.recording_id}/transcription"
)
assert response.status_code == 200
data = response.json()
assert data["recording_id"] == self.recording_id
assert data["status"] == "pending"
def test_get_transcription_not_found(self):
"""Test getting transcription for recording without transcription."""
response = client.get(
f"/api/recordings/{self.recording_id}/transcription"
)
assert response.status_code == 404
class TestAuditLog:
"""Tests for audit log endpoints."""
def test_get_audit_log(self):
"""Test retrieving audit log entries."""
response = client.get("/api/recordings/audit/log")
assert response.status_code == 200
data = response.json()
assert "entries" in data
assert "total" in data
def test_get_audit_log_filter_by_action(self):
"""Test filtering audit log by action."""
response = client.get("/api/recordings/audit/log?action=created")
assert response.status_code == 200
class TestHealthCheck:
"""Tests for health check endpoint."""
def test_health_check(self):
"""Test health check returns healthy status."""
response = client.get("/api/recordings/health")
assert response.status_code == 200
data = response.json()
assert data["status"] == "healthy"
assert "recordings_count" in data
assert "minio_endpoint" in data