Cybersecurity-Projects/PROJECTS/encrypted-p2p-chat/backend/tests/conftest.py

210 lines
5.0 KiB
Python

"""
ⒸAngelaMos | 2025
Pytest configuration and fixtures for all tests
"""
import asyncio
from uuid import uuid4
from typing import Any
from collections.abc import AsyncGenerator
import pytest
import pytest_asyncio
from sqlmodel import SQLModel
from sqlalchemy.ext.asyncio import (
AsyncSession,
create_async_engine,
)
from sqlalchemy.orm import sessionmaker
from webauthn.helpers import bytes_to_base64url
from app.models.User import User
from app.models.IdentityKey import IdentityKey
from app.models.SignedPrekey import SignedPrekey
from app.models.OneTimePrekey import OneTimePrekey
from app.core.encryption.x3dh_manager import x3dh_manager
@pytest.fixture(scope = "session")
def event_loop():
"""
Create event loop for async tests
"""
loop = asyncio.get_event_loop_policy().new_event_loop()
yield loop
loop.close()
@pytest_asyncio.fixture(scope = "function")
async def db_session() -> AsyncGenerator[AsyncSession]:
"""
Create in-memory SQLite database for testing
"""
engine = create_async_engine(
"sqlite+aiosqlite:///:memory:",
echo = False,
future = True,
)
async with engine.begin() as conn:
await conn.run_sync(SQLModel.metadata.create_all)
async_session = sessionmaker(
bind = engine,
class_ = AsyncSession,
expire_on_commit = False,
)
async with async_session() as session:
yield session
await session.rollback()
await engine.dispose()
@pytest_asyncio.fixture
async def test_user(db_session: AsyncSession) -> User:
"""
Create test user
"""
user = User(
username = "testuser",
display_name = "Test User",
is_active = True,
is_verified = True,
)
db_session.add(user)
await db_session.commit()
await db_session.refresh(user)
return user
@pytest_asyncio.fixture
async def test_user_2(db_session: AsyncSession) -> User:
"""
Create second test user for conversations
"""
user = User(
username = "testuser2",
display_name = "Test User 2",
is_active = True,
is_verified = True,
)
db_session.add(user)
await db_session.commit()
await db_session.refresh(user)
return user
@pytest_asyncio.fixture
async def test_identity_key(
db_session: AsyncSession,
test_user: User
) -> IdentityKey:
"""
Create identity key for test user
"""
ik_private_x25519, ik_public_x25519 = (
x3dh_manager.generate_identity_keypair_x25519()
)
ik_private_ed25519, ik_public_ed25519 = (
x3dh_manager.generate_identity_keypair_ed25519()
)
identity_key = IdentityKey(
user_id = test_user.id,
public_key = ik_public_x25519,
private_key = ik_private_x25519,
public_key_ed25519 = ik_public_ed25519,
private_key_ed25519 = ik_private_ed25519,
)
db_session.add(identity_key)
await db_session.commit()
await db_session.refresh(identity_key)
return identity_key
@pytest_asyncio.fixture
async def test_signed_prekey(
db_session: AsyncSession,
test_user: User,
test_identity_key: IdentityKey
) -> SignedPrekey:
"""
Create signed prekey for test user
"""
spk_private, spk_public, spk_signature = x3dh_manager.generate_signed_prekey(
test_identity_key.private_key_ed25519
)
signed_prekey = SignedPrekey(
user_id = test_user.id,
key_id = 1,
public_key = spk_public,
private_key = spk_private,
signature = spk_signature,
is_active = True,
)
db_session.add(signed_prekey)
await db_session.commit()
await db_session.refresh(signed_prekey)
return signed_prekey
@pytest_asyncio.fixture
async def test_one_time_prekey(
db_session: AsyncSession,
test_user: User
) -> OneTimePrekey:
"""
Create one-time prekey for test user
"""
opk_private, opk_public = x3dh_manager.generate_one_time_prekey()
one_time_prekey = OneTimePrekey(
user_id = test_user.id,
key_id = 1,
public_key = opk_public,
private_key = opk_private,
is_used = False,
)
db_session.add(one_time_prekey)
await db_session.commit()
await db_session.refresh(one_time_prekey)
return one_time_prekey
@pytest.fixture
def mock_webauthn_credential() -> dict[str, Any]:
"""
Mock WebAuthn credential response
"""
return {
"id": bytes_to_base64url(uuid4().bytes),
"rawId": bytes_to_base64url(uuid4().bytes),
"type": "public-key",
"response": {
"clientDataJSON": bytes_to_base64url(b'{"type":"webauthn.create"}'),
"attestationObject": bytes_to_base64url(b"mock_attestation"),
},
}
@pytest.fixture
def sample_plaintext() -> str:
"""
Sample message for encryption tests
"""
return "Hello, this is a test message!"
@pytest.fixture
def sample_associated_data() -> bytes:
"""
Sample associated data for AEAD
"""
return b"test_sender:test_recipient"