Files
wehub-resource-sync 7a0da7932b
OSV-Scanner (Scheduled) / scan-scheduled (push) Failing after 0s
Create Release / test-gate (push) Has been cancelled
Create Release / release-gate (push) Has been cancelled
Create Release / ci-gate (push) Has been cancelled
Create Release / version-check (push) Has been cancelled
Create Release / e2e-test-gate (push) Has been cancelled
Create Release / responsive-test-gate (push) Has been cancelled
Create Release / compat-test-gate (push) Has been cancelled
Create Release / compose-integration-gate (push) Has been cancelled
Create Release / vulture-gate (push) Has been cancelled
Create Release / build (push) Has been cancelled
Create Release / provenance (push) Has been cancelled
Create Release / prerelease-docker (push) Has been cancelled
Create Release / publish-docker (push) Has been cancelled
Create Release / create-release (push) Has been cancelled
Create Release / cleanup-changelog (push) Has been cancelled
Create Release / trigger-pypi (push) Has been cancelled
Create Release / monitor-pypi (push) Has been cancelled
Create Release / Clean up orphan prerelease tags and signatures (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-form] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-metrics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-workflow] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-core] (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [history-news] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [library] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [link-analytics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-core] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-lifecycle] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [error-benchmark] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) (push) Has been cancelled
Docker Tests (Consolidated) / Accessibility Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Unit Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Example Tests (push) Has been cancelled
Docker Tests (Consolidated) / Production Image Smoke Test (push) Has been cancelled
Docker Tests (Consolidated) / Infrastructure Tests (push) Has been cancelled
OSSF Scorecard / OSSF Security Scorecard Analysis (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [mobile] (push) Has been cancelled
Backwards Compatibility / Verify Encryption Constants (push) Has been cancelled
Backwards Compatibility / PyPI Version Compatibility (push) Has been cancelled
Backwards Compatibility / Database Migration Tests (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Docker Tests (Consolidated) / detect-changes (push) Has been cancelled
Docker Tests (Consolidated) / Build Test Image (push) Has been cancelled
Docker Tests (Consolidated) / All Pytest Tests + Coverage (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [accessibility] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [api-crud] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-login] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-register] (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:08:55 +08:00

199 lines
6.2 KiB
Python

"""Tests for authentication-related database models."""
from datetime import datetime, timezone
import pytest
from sqlalchemy import create_engine
from sqlalchemy.exc import IntegrityError
from sqlalchemy.orm import sessionmaker
from local_deep_research.database.models import Base, User
class TestUserModel:
"""Test suite for the User model."""
@pytest.fixture
def engine(self):
"""Create an in-memory SQLite database for testing."""
engine = create_engine("sqlite:///:memory:")
Base.metadata.create_all(engine)
yield engine
engine.dispose()
@pytest.fixture
def session(self, engine):
"""Create a database session for testing."""
Session = sessionmaker(bind=engine)
session = Session()
yield session
session.close()
def test_create_user(self, session):
"""Test creating a new user."""
user = User(username="testuser")
session.add(user)
session.commit()
# Retrieve the user
saved_user = session.query(User).filter_by(username="testuser").first()
assert saved_user is not None
assert saved_user.username == "testuser"
assert saved_user.created_at is not None
assert saved_user.database_version == 1
def test_unique_username_constraint(self, session):
"""Test that usernames must be unique."""
user1 = User(username="testuser")
session.add(user1)
session.commit()
# Try to create another user with the same username
user2 = User(username="testuser")
session.add(user2)
with pytest.raises(IntegrityError):
session.commit()
def test_user_timestamps(self, session):
"""Test that created_at is set correctly."""
user = User(username="testuser")
# Before saving, created_at should be None
assert user.created_at is None
session.add(user)
session.commit()
# After saving, created_at should be set
assert user.created_at is not None
assert isinstance(user.created_at, datetime)
# Update last_login
user.last_login = datetime.now(timezone.utc)
session.commit()
# Verify last_login is set
assert user.last_login is not None
assert user.last_login >= user.created_at
def test_user_last_login(self, session):
"""Test last_login timestamp."""
user = User(username="testuser")
session.add(user)
session.commit()
# Initially last_login should be None
assert user.last_login is None
# Update last_login
login_time = datetime.now(timezone.utc)
user.last_login = login_time
session.commit()
# Verify last_login is set
saved_user = session.query(User).filter_by(username="testuser").first()
assert saved_user.last_login is not None
assert abs((saved_user.last_login - login_time).total_seconds()) < 1
def test_user_representation(self):
"""Test string representation of User model."""
user = User(username="testuser")
# Should have a meaningful string representation
assert repr(user) == "<User testuser>"
def test_database_path_property(self):
"""Test the database_path property generates consistent paths."""
user1 = User(username="testuser")
user2 = User(username="testuser")
user3 = User(username="different")
# Same username should generate same path
assert user1.database_path == user2.database_path
# Different username should generate different path
assert user1.database_path != user3.database_path
# Path should have expected format
assert user1.database_path.startswith("ldr_user_")
assert user1.database_path.endswith(".db")
def test_database_version_default(self, session):
"""Test that database_version defaults to 1."""
user = User(username="testuser")
session.add(user)
session.commit()
assert user.database_version == 1
# Can update version
user.database_version = 2
session.commit()
saved_user = session.query(User).filter_by(username="testuser").first()
assert saved_user.database_version == 2
def test_username_with_special_characters(self, session):
"""Test usernames with special characters."""
special_users = [
"user@email.com",
"user-with-dashes",
"user_with_underscores",
"user.with.dots",
"user123",
"UPPERCASE",
"مستخدم", # Arabic
"用户", # Chinese
"🎉user", # Emoji
]
for username in special_users:
user = User(username=username)
session.add(user)
session.commit()
# All should be saved successfully
assert session.query(User).count() == len(special_users)
# Each should have a valid database path
for username in special_users:
user = session.query(User).filter_by(username=username).first()
assert user is not None
assert user.database_path.startswith("ldr_user_")
assert user.database_path.endswith(".db")
# Path should be filesystem-safe (no special chars)
assert all(c.isalnum() or c in "_." for c in user.database_path)
def test_user_query_operations(self, session):
"""Test various query operations on User model."""
# Create multiple users
users = []
for i in range(5):
user = User(username=f"user{i}")
users.append(user)
session.add(user)
session.commit()
# Query all users
all_users = session.query(User).all()
assert len(all_users) == 5
# Query by username
user2 = session.query(User).filter_by(username="user2").first()
assert user2 is not None
assert user2.username == "user2"
# Query ordered by created_at
ordered_users = session.query(User).order_by(User.created_at).all()
assert len(ordered_users) == 5
# Query with limit
limited_users = session.query(User).limit(3).all()
assert len(limited_users) == 3