원클릭으로
test-generation
Use this skill to write tests for VoxBento features. All tests use `pytest` + `anyio`. Reference: `tests/conftest.py`.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Use this skill to write tests for VoxBento features. All tests use `pytest` + `anyio`. Reference: `tests/conftest.py`.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Use this skill to evaluate proposed architecture changes against VoxBento's design principles.
Use this skill to find files, understand module ownership, and locate code in VoxBento.
Use this skill to analyse, audit, or modify HTTP and WebSocket routes in VoxBento. All routes live in `portal/routers/`.
Use this skill for security reviews of VoxBento code. Covers OWASP Top 10 and VoxBento-specific threat model.
Use this skill for tasks involving transcription providers, caption streaming, or the audio pipeline. Reference: `portal/transcription/`, [TRANSCRIPTION_MAP.md](../../context/TRANSCRIPTION_MAP.md).
Use this skill to analyse, audit, or modify database models, migrations, and CRUD helpers. Reference: `portal/models.py`, `portal/database.py`, `alembic/versions/`.
| name | test-generation |
| description | Use this skill to write tests for VoxBento features. All tests use `pytest` + `anyio`. Reference: `tests/conftest.py`. |
Use this skill to write tests for VoxBento features. All tests use
pytest+anyio. Reference:tests/conftest.py.
tests/conftest.py)pytest_plugins = ('anyio',)
@pytest.fixture(params=['asyncio'])
def anyio_backend(request):
return request.param
All async tests use @pytest.mark.anyio or @pytest.mark.asyncio.
import pytest
from portal.database import configure, init_db, drop_db, get_session
@pytest.fixture(autouse=True)
async def test_db():
configure('sqlite+aiosqlite:///:memory:')
await init_db()
yield
await drop_db()
import pytest
from httpx import AsyncClient, ASGITransport
from fastapi_app import app
@pytest.fixture
async def client():
async with AsyncClient(transport=ASGITransport(app=app), base_url='http://test') as c:
yield c
tests/test_booth_state.py)from portal.booth_state import BoothRegistry
async def test_join_participant():
registry = BoothRegistry()
participant, state = await registry.join_participant(
booth_id='test-en',
display_name='Alice',
role='interpreter',
language='English',
channel_id='test/en',
)
assert participant.role == 'interpreter'
assert state['active_interpreter_id'] == participant.participant_id
tests/test_database.py)from portal.database import create_event, create_room, create_booth, get_session
async def test_create_event(test_db):
async with get_session() as session:
ev = await create_event(session, slug='myevent', display_name='My Event')
assert ev.id is not None
assert ev.slug == 'myevent'
tests/test_fastapi_app.py)async def test_healthz(client):
resp = await client.get('/healthz')
assert resp.status_code == 200
data = resp.json()
assert data['ok'] is True
async def test_login_invalid(client):
resp = await client.post('/login', data={'email': 'x@x.com', 'password': 'wrong'})
assert resp.status_code == 403
tests/test_user_auth.py)from portal.auth import create_user_token, decode_token
def test_user_token_roundtrip():
token = create_user_token(user_id=1, email='a@b.com', display_name='Alice', is_admin=False)
payload = decode_token(token)
assert payload['sub'] == '1'
assert payload['user'] is True
assert payload['is_admin'] is False
tests/test_join_flow.py)async def test_invite_token_join(client, test_db):
# Setup: create event, room, booth, token via DB helpers
async with get_session() as session:
ev = await create_event(session, slug='test', display_name='T')
room = await create_room(session, event_id=ev.id, display_name='R')
booth = await create_booth(session, event_id=ev.id, room_id=room.id,
language_code='en', language_name='English')
token = await create_invite_token(session, booth_id=booth.id, role='interpreter')
resp = await client.get(f'/join/{token.token}', follow_redirects=False)
assert resp.status_code == 303
assert '/interpreter/test/en' in resp.headers['location']
assert 'session_token' in resp.cookies
async def test_ws_booth_join(client, test_db):
# Setup booth + user with role
...
async with client.websocket_connect(f'/ws/booth/test-en') as ws:
await ws.send_json({
'type': 'booth:join',
'display_name': 'Alice',
'role': 'interpreter',
'language': 'English',
'channel_id': 'test/en',
})
msg = await ws.receive_json()
assert msg['type'] == 'booth:joined'
| Test area | File |
|---|---|
| Route/HTTP | tests/test_fastapi_app.py |
| Booth state logic | tests/test_booth_state.py |
| Booth identity scheme | tests/test_booth_identity.py |
| DB CRUD | tests/test_database.py |
| Admin panel | tests/test_admin_panel.py |
| Roles + permissions | tests/test_roles.py |
| Crypto | tests/test_crypto.py |
| User auth | tests/test_user_auth.py |
| Invite token join | tests/test_join_flow.py |
| Memberships | tests/test_memberships_tokens.py |
| Transcription | tests/test_transcription_concurrency.py |
CaptionAggregator forced finalization (50 words, 15 seconds).BoothRegistry.set_active_interpreter permission denial._ensure_mediamtx_path cache invalidation path.redeem_invite_token → already used + expired cases.